473,386 Members | 1,679 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Crazy (?) C problem

Hello,

I'm using the intel C++ 8.0 compiler on windows and I'm working on some
software that uses the following lines of code:

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);

dim is an integer, gf->invdim a double. I always get "-1.#IND00" as the
output of this code, no matter the value of dim, but only at certain
stages in the code.

If I duplicate the code like so:

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);
gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);

The first output is the NAN but the second is the expected result.

I thought I understood C pretty well, but this is weirding me out.

I realize that this is grossly out of context but the program is pretty
complicated and I don't think it would help understand this anyway.

If anyone here has an insight, I'd be much obliged.

Jason Sewall
Nov 14 '05 #1
14 1551
Sorry, here's a quick followup (very quick, I posted the parent just two
minutes ago).

I compiled it with intel 8.0 in "Release" mode. No problem. (The problem
described in parent occured in intel "debug" mode.

In MSVC 6 Debug, no problem. Ditto for Release.

There must be some sort of bug in my program that only intel debug
exposes, a bug in intel, or some weird debug setting that I don't
understand.

Anyway, your comments are welcome!

Jason
Jason Sewall wrote:
Hello,

I'm using the intel C++ 8.0 compiler on windows and I'm working on some
software that uses the following lines of code:

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);

dim is an integer, gf->invdim a double. I always get "-1.#IND00" as the
output of this code, no matter the value of dim, but only at certain
stages in the code.

If I duplicate the code like so:

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);
gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);

The first output is the NAN but the second is the expected result.

I thought I understood C pretty well, but this is weirding me out.

I realize that this is grossly out of context but the program is pretty
complicated and I don't think it would help understand this anyway.

If anyone here has an insight, I'd be much obliged.

Jason Sewall


Nov 14 '05 #2
Jason Sewall wrote:
Hello,

I'm using the intel C++ 8.0 compiler on windows and I'm working on some
software that uses the following lines of code:

gf->invdim = 1.0/(double)dim; ^^^^^^
pointless cast, the conversion to floating point is triggered by the 1.0 printf("invdim: %f\n", (float)gf->invdim);

^^^^^^^
pointless cast. %f is the specifier for a double
Nov 14 '05 #3
Jason Sewall wrote:

Hello,

I'm using the intel C++ 8.0 compiler on windows and I'm working on some
software that uses the following lines of code:

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);
The cast is pointless. printf will receive the value as a double anyway.
dim is an integer, gf->invdim a double. I always get "-1.#IND00" as the
output of this code, no matter the value of dim, but only at certain
stages in the code.
I can see nothing in the code you posted that would provoke such an
output (unless dim were 0, which I presume you already considered).
If anyone here has an insight, I'd be much obliged.


The problem almost certainly lies elsewhere. I believe that you are
looking at the bomb's landing site, not its launch site. I wouldn't
like to speculate on possible causes without seeing the code.
Nov 14 '05 #4
Jason Sewall wrote:
.... snip ...
gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);


printf is a variadic function. %f expects a double argument. You
are casting the argument to a float, thus invoking undefined
behaviour. I also see no sign of #include <stdio.h>.

All casts are inherently suspicious.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 14 '05 #5
CBFalconer wrote:
Jason Sewall wrote:
... snip ...

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);


printf is a variadic function. %f expects a double argument. You
are casting the argument to a float, thus invoking undefined
behaviour.


Not directly. It's only undefined behaviour if gf->invdim is not
representable as a float. The cast will not stop the implicit promotion
back to double, as per default argument promotions.
I also see no sign of #include <stdio.h>.

All casts are inherently suspicious.


--
Peter

Nov 14 '05 #6
CBFalconer <cb********@yahoo.com> writes:
Jason Sewall wrote:
... snip ...

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);


printf is a variadic function. %f expects a double argument. You
are casting the argument to a float, thus invoking undefined
behaviour.


But the float is then promoted to double.
I also see no sign of #include <stdio.h>.
Or of a main program (it's just a code snippet). But if
"#include <stdio.h" is missing, you should definitely add it.
All casts are inherently suspicious.


Agreed.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #7
About the explicit double cast; this has no effect on the code, correct?
I prefer an explicit cast where possible to eliminate any confusion.

About the printf formatting: I thought %f expected a float, not a
double, hence the cast.

As for comments about including stdio.h, it has been included outside
the snippet shown here. In fact, there's a whole program around that
snippet of code. I surprised nobody pointed out that there's no
declaration of gf or its members, or dim. In fact, there isn't even a
main() statement!

The sarcasm is simply to point out that I wanted you all to assume that
it had those things that every C program does.

At any rate, the only think I can think of is that I have some
assignment to a void pointer somewhere that's corrupting the data in the
program. Whatever, I'll just use the release mode to get the project
finished. I'll clean up the code later and see if the bug shows up.

On that note, any suggestions on software for testing for memory leaks
on windows?

Thanks,
Jason

Keith Thompson wrote:
CBFalconer <cb********@yahoo.com> writes:
Jason Sewall wrote:

... snip ...
gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);


printf is a variadic function. %f expects a double argument. You
are casting the argument to a float, thus invoking undefined
behaviour.

But the float is then promoted to double.

I also see no sign of #include <stdio.h>.

Or of a main program (it's just a code snippet). But if
"#include <stdio.h" is missing, you should definitely add it.

All casts are inherently suspicious.

Agreed.

Nov 14 '05 #8
"Jason Sewall" <js*****@fake.com> wrote in message
news:41********@news.unc.edu...
About the explicit double cast;
this has no effect on the code, correct?
It could give incorrect results.
It could slow it down (but probably not noticeably).
I prefer an explicit cast
casting is explicit by definition.
where possible to eliminate any confusion.
Your code can *cause* confusion by giving a wrong answer.
It exposes *your* confusion about how C works.

About the printf formatting: I thought %f expected a float, not a
double, hence the cast.
Back to the books for you! :-)

(A good 'rule of thumb' (as Chuck alluded) is:
Treat with suspicion every cast you see and every
inclination you have to cast).

Hmm, I feel a .sig coming on...
"Casts cast suspicion upon the code."

(Sometimes a cast is indeed the only way to do
something, but you should be *certain* you
know what you're doing, and why).
As for comments about including stdio.h, it has been included outside
the snippet shown here.
It's always best to post compilable code if at all possible.
If your code is large, pare it down to a (still compilable)
example that still reproduces the problem you're asking about.
In fact, there's a whole program around that
snippet of code. I surprised nobody pointed out that there's no
declaration of gf or its members, or dim.
This means that answers you get are only educated guesses
and cannot conclusively explain your program's behavior.
In fact, there isn't even a
main() statement!
main() is a function, not a statement. Also, a file
containing compilable C code need not contain a 'main()'
function at all (most nontrivial C programs are composed
of many source files, and only one will contain a 'main()'
function.)

The sarcasm
What sarcasm?
is simply to point out that I wanted you all to assume

Hah!
that
it had those things that every C program does.
A huge number of posts here contain code claimed to
be "C programs" which really are not.

At any rate, the only think I can think of is that I have some
assignment to a void pointer somewhere that's corrupting the data in the
program. Whatever, I'll just use the release mode to get the project
finished. I'll clean up the code later and see if the bug shows up.
Why not actually analyze the problem and really solve it?
Just guessing will often simply dig you deeper into trouble.
Do some testing and use your debugger.
On that note, any suggestions on software for testing for memory leaks
on windows?


Not topical here. Try a Windows group.

Finally, please don't top-post in comp.lang.c

-Mike
Nov 14 '05 #9
Jason Sewall wrote:

As for comments about including stdio.h, it has been included
outside the snippet shown here. In fact, there's a whole program
around that snippet of code. I surprised nobody pointed out that
there's no declaration of gf or its members, or dim. In fact,
there isn't even a main() statement!
Nitpick - main() is not a statement (it's a function).
The sarcasm is simply to point out that I wanted you all to
assume that it had those things
To assume makes an ASS out of U and ME. It was quite credible
that your problem was caused by omitting the "#include <stdio.h>"
(because then printf() would have been declared incorrectly, and
you had reported problems with printf's behaviour).
that every C program does.
You'd be surprised how many programs don't have those things.
At any rate, the only think I can think of is that I have some
assignment to a void pointer somewhere that's corrupting the data in the program. Whatever,
Try posting a compilable program that demonstrates the problem.
I'll just use the release mode to get the project
finished. I'll clean up the code later and see if the bug shows up.


Most likely, it will show up just when you have to demo the code
to someone important.

Nov 14 '05 #10
Peter Nilsson wrote:
CBFalconer wrote:
Jason Sewall wrote:

... snip ...

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);


printf is a variadic function. %f expects a double argument. You
are casting the argument to a float, thus invoking undefined
behaviour.


Not directly. It's only undefined behaviour if gf->invdim is not
representable as a float.


It's only undefined if gf->invdim is outside the range of float.
If it is in the range but not representable exactly as float, then
it must be rounded to one of the two nearest values in an I-D manner
(that's how I am reading C99, anyway).

Also, some people have suggested the cast is pointless. It would
be useful if you wanted to investigate what happened when the
double in question is rounded to a float (for example, if you had
noticed strange behaviour when calling a function prototyped
to take a float parameter).

Nov 14 '05 #11
"Mike Wahler" <mk******@mkwahler.net> writes:
"Jason Sewall" <js*****@fake.com> wrote in message
news:41********@news.unc.edu...
About the explicit double cast;
this has no effect on the code, correct?
It could give incorrect results.
It could slow it down (but probably not noticeably).
I prefer an explicit cast


casting is explicit by definition.
where possible to eliminate any confusion.


Your code can *cause* confusion by giving a wrong answer.
It exposes *your* confusion about how C works.


That's a little harsh. The original context (lost in the followups)
was:

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);

where dim is an integer and gv->invdim isa double.

The constant 1.0 is of type double (as is any unsuffixed floating
constant), so if the cast is omitted:

1.0/dim

the value of dim will be converted to double. The cast, in this
particular case, is redundant but harmless.

Casts are inherently suspicious because they do too much, and C has
enough implicit conversions that casts are usually unnecessary. In
many cases, a cast tells the compiler "I know what I'm doing; shut up
and doing what I say" -- which is dangerous if you *don't* know what
you're doing. The classic example is casting the result of malloc(),
which can (in C90) mask the error of omitting the "#include <stdlib.h>".

But casts from one numeric type to another are *relatively* harmless,
since they convert the value rather than just copying the bits (as
pointer casts often do).

Casts are like gotos. They have legitimate uses, but their abuse has
caused any use of them to be suspicious.

[...]
As for comments about including stdio.h, it has been included outside
the snippet shown here.
And we had no way of knowing that.
It's always best to post compilable code if at all possible.
If your code is large, pare it down to a (still compilable)
example that still reproduces the problem you're asking about.


That's good advice. In fact, in the process of narrowing down your
code to a small compilable snippet, you'll often solve the problem
yourself.

But this case may be one of the rare exceptions. The symptom was
showing up in a 2-line code snippet. Duplicating that snippet changed
the symptoms, which didn't make much sense. It might not have been
possible to narrow down the program while still exhibiting the
problem.

[...]
At any rate, the only think I can think of is that I have some
assignment to a void pointer somewhere that's corrupting the data in the
program. Whatever, I'll just use the release mode to get the project
finished. I'll clean up the code later and see if the bug shows up.


What do you mean by "assignment to a void pointer"? Do you mean a
null pointer?

Probably something executed before the snippet you showed us invoked
undefined behavior and corrupted something somewhere. There are
numerous things that can cause undefined behavior.

Compile your code with the highest possible warning and optimization
levels (higher optization levels cause the compiler to do more
analysis, which can allow it to detect more errors). Run it under a
debugger. Examine everything you can, including address and values of
variables (gf is a pointer; see what address it points to). If
anything looks odd, trace back in your program and see how it got that
way.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #12

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Mike Wahler" <mk******@mkwahler.net> writes:
"Jason Sewall" <js*****@fake.com> wrote in message
news:41********@news.unc.edu...
About the explicit double cast;
this has no effect on the code, correct?
It could give incorrect results.
It could slow it down (but probably not noticeably).
I prefer an explicit cast


casting is explicit by definition.
where possible to eliminate any confusion.


Your code can *cause* confusion by giving a wrong answer.
It exposes *your* confusion about how C works.


That's a little harsh.


Perhaps. That wasn't my intention.
The original context (lost in the followups)
was:

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);

where dim is an integer and gv->invdim isa double.

The constant 1.0 is of type double (as is any unsuffixed floating
constant), so if the cast is omitted:

1.0/dim

the value of dim will be converted to double. The cast, in this
particular case, is redundant but harmless.
I was talking about the cast of 'invdim' to 'float'.

Casts are inherently suspicious because they do too much, and C has
enough implicit conversions that casts are usually unnecessary. In
many cases, a cast tells the compiler "I know what I'm doing; shut up
and doing what I say" -- which is dangerous if you *don't* know what
you're doing.
In this case (the cast to 'float') I think that is the case.

The classic example is casting the result of malloc(),
which can (in C90) mask the error of omitting the "#include <stdlib.h>".

But casts from one numeric type to another are *relatively* harmless,
since they convert the value rather than just copying the bits (as
pointer casts often do).
But my point was that casting a double to a float
can lose information.

Casts are like gotos. They have legitimate uses, but their abuse has
caused any use of them to be suspicious.
Yes.
It's always best to post compilable code if at all possible.
If your code is large, pare it down to a (still compilable)
example that still reproduces the problem you're asking about.
That's good advice. In fact, in the process of narrowing down your
code to a small compilable snippet, you'll often solve the problem
yourself.


Yes.

But this case may be one of the rare exceptions. The symptom was
showing up in a 2-line code snippet. Duplicating that snippet changed
the symptoms, which didn't make much sense. It might not have been
possible to narrow down the program while still exhibiting the
problem.


I was responding to OP's:

"About the printf formatting: I thought %f expected a float, not a
double, hence the cast."

-Mike
Nov 14 '05 #13
"Mike Wahler" <mk******@mkwahler.net> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...

[...]
That's a little harsh.


Perhaps. That wasn't my intention.
The original context (lost in the followups)
was:

gf->invdim = 1.0/(double)dim;
printf("invdim: %f\n", (float)gf->invdim);

where dim is an integer and gv->invdim isa double.

The constant 1.0 is of type double (as is any unsuffixed floating
constant), so if the cast is omitted:

1.0/dim

the value of dim will be converted to double. The cast, in this
particular case, is redundant but harmless.


I was talking about the cast of 'invdim' to 'float'.


Sorry, I missed that; I thought you were talking about (double)dim.

The cast to float is also a numeric-to-numeric cast, so it doesn't
have the same pitfalls that pointer casts can have, but yes, it does
potentially lose information.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #14
On Sat, 15 Jan 2005 23:54:39 -0500, Jason Sewall wrote:
Sorry, here's a quick followup (very quick, I posted the parent just two
minutes ago).

I compiled it with intel 8.0 in "Release" mode. No problem. (The problem
described in parent occured in intel "debug" mode.

In MSVC 6 Debug, no problem. Ditto for Release.

There must be some sort of bug in my program that only intel debug
exposes, a bug in intel, or some weird debug setting that I don't
understand.


There's nothing obviously wrong in the code you posted. There could easily
be something wrong in the code you haven't posted which ends up affecting
the output of this code. You may alternatively have found a genuine
compiler bug. In order to investigate this further you should create a
minimal program that demonstrates the problem. That should be easy enough
to do by cutting down your existing program until just before the point
where the code works. Hopefully you will then have a program small enough
to post in its entirety.

Lawrence
Nov 14 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: doltharz | last post by:
Please Help me i'm doing something i though was to be REALLY EASY but it drives me crazy The complete code is at the end of the email (i mean newsgroup article), i always use Option...
3
by: alef | last post by:
Hi, I have the following code which is driving me crazy. I compile it on MacOSX and it keeps crashing upon entering a command in the program (ran trough gdb) pwd Program received signal...
8
by: Islam Elkhayat | last post by:
I need help plzzzz... In my windows application i fill listview from simple access database... here is the code //Creating colums InitializeComponent();...
3
by: Larry Tate | last post by:
I have had a monstrous time getting any good debugging info out of the .net platform. Using ... ..NET Framework 1.1 Windows 2K Server VB.NET <- is this the problem? error handling in the...
1
by: Maileen | last post by:
Hi, I'm still with my problem of string resource to load from a C++ DLL. Here is my code : in my module i have the function for loading DLL and sending back a string to main form. where...
3
by: squash | last post by:
I have spent two hours trying to make sense of this script, called crazy.php. The output should be nothing because $cookie_password is nowhere defined in this script, correct? But it actually...
28
by: onkar | last post by:
This idea might be vey crazy. But I hope to get answers to this .. from comp.lang.c If a compiler is designed such that it automatically adds a free() matching every malloc() then is it not a...
3
by: rashpal.sidhu | last post by:
Please help, this problem is driving me crazy !! I am using metaphone to create phonetic keys. When i run the module stand-a-lone it works fine. I'm trying to create a runner for informix...
3
by: vikassawant | last post by:
hi, My problem is some what crazy for me. Let's see, I declare one java file named as, test1.java. In which i designed required GUI for project i.e 8 combobox,two buttons,etc....
1
by: DaMasta | last post by:
hi..im new to the community and was finally so fustrated with guessing that i figured i'd try to get some help (and from my writing..you can probably tell im not exactly 40 years old) oki..here's...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.