Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Crazy (?) C problem

Reply
Thread Tools

Crazy (?) C problem

 
 
Old Wolf
Guest
Posts: n/a
 
      01-16-2005
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).

 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      01-16-2005
"Mike Wahler" <(E-Mail Removed)> writes:
> "Jason Sewall" <(E-Mail Removed)> wrote in message
> news:41eaa722$(E-Mail Removed)...
>> 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) http://www.velocityreviews.com/forums/(E-Mail Removed) <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.
 
Reply With Quote
 
 
 
 
Mike Wahler
Guest
Posts: n/a
 
      01-17-2005

"Keith Thompson" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "Mike Wahler" <(E-Mail Removed)> writes:
> > "Jason Sewall" <(E-Mail Removed)> wrote in message
> > news:41eaa722$(E-Mail Removed)...
> >> 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


 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-17-2005
"Mike Wahler" <(E-Mail Removed)> writes:
> "Keith Thompson" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...

[...]
>> 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) (E-Mail Removed) <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.
 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      01-17-2005
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Crazy jar resource access problem JavaEnquirer Java 7 02-27-2006 10:30 AM
Crazy Image Problem Mr Newbie ASP .Net 3 09-22-2005 05:20 AM
crazy problem with strtok puttings ptrs in **argv alef@xs4all.nl C Programming 3 07-27-2005 04:37 AM
crazy browser go crazy dr greg Computer Support 7 01-14-2005 09:13 PM
CRAZY new problem I have never seen affecting 3750G and 2970G ccs Cisco 0 07-30-2004 02:38 AM



Advertisments