Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Bug in GCC?

Reply
Thread Tools

Bug in GCC?

 
 
boltar2003@boltar.world
Guest
Posts: n/a
 
      05-12-2010
hi

Can someone tell me whats going on here. I'm using gcc 4.3.3 in linux.
Have I missed something obvious in the code snippet below or is there some
odd casting bug going on with gcc?

$ cat t.c
#include <stdio.h>

main()
{
double d = -2.345;
printf("%f\n",(double)(1 ? (int)d : (unsigned int)1));
}
$ cc t.c
$ ./a.out
4294967294.000000

If you change unsigned int to unsigned char then you get -2 as expected as
the result.

B2003

 
Reply With Quote
 
 
 
 
Pramod Subramanyan
Guest
Posts: n/a
 
      05-12-2010
The type of (1 ? (int)d : (unsigned int)1) is unsigned int. So d is
being cast to (int) -2, which in turn is cast to (unsigned)
4294967294. Your final cast takes it from (unsigned) 4294967294 to
(double) 4294967294.

--pramod
 
Reply With Quote
 
 
 
 
William Hughes
Guest
Posts: n/a
 
      05-12-2010
On May 12, 11:08*am, boltar2...@boltar.world wrote:
> hi
>
> Can someone tell me whats going on here. I'm using gcc 4.3.3 in linux.
> Have I missed something obvious in the code snippet below or is there some
> odd casting bug going on with gcc?
>
> $ cat t.c
> #include <stdio.h>
>
> main()
> {
> * * * * double d = -2.345;
> * * * * printf("%f\n",(double)(1 ? (int)d : (unsigned int)1));}
>
> $ cc t.c
> $ ./a.out
> 4294967294.000000
>
> If you change unsigned int to unsigned char then you get -2 as expected as
> the result.
>
> B2003


The point is that the type of x?y:z depends on the types
of both y *and* z. The fact that z is not evaluated does not
matter. If y is int and z is of unsigned int, x?y:z is of unsigned
int, if y is int and z is unsigned char, x?y:z is type int.
(double)((unsigned int)((int) d)) = 4294967294.000000

- William Hughes
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      05-12-2010
On 5/12/2010 10:08 AM, d wrote:
> hi
>
> Can someone tell me whats going on here. I'm using gcc 4.3.3 in linux.
> Have I missed something obvious in the code snippet below or is there some
> odd casting bug going on with gcc?
>
> $ cat t.c
> #include<stdio.h>
>
> main()
> {
> double d = -2.345;
> printf("%f\n",(double)(1 ? (int)d : (unsigned int)1));
> }
> $ cc t.c
> $ ./a.out
> 4294967294.000000


Right. (Well, it depends on the value of UINT_MAX, but on
most 32-bit systems this is what you should expect.)

> If you change unsigned int to unsigned char then you get -2 as expected as
> the result.


Right again.

Remember, every expression in C has a single type, fixed at
compile time and immutable thereafter. In particular, the type
of `x?y:z' is one type, not "sometimes the type of y and sometimes
the type of z, depending on x." So, what happens when y and z
start out as different types? The same thing that happens when
you compute `y+z' or `y>z' or pretty much anything else: The "usual
arithmetic conversions" are performed, and the result has the type
that those conversions produce. So, what's the type of `-2 + 1u'?
And what's the type of `1 ? -2 : 1u'?

By the way, if you crank up gcc's warning levels it will tell
you "warning: signed and unsigned type in conditional expression."
I think it's good practice to crank up the warnings as high as your
code can stand -- and even if you don't routinely put them to the
max, you should *definitely* do so when confronted with a mystery.

--
Eric Sosman
lid
 
Reply With Quote
 
boltar2003@boltar.world
Guest
Posts: n/a
 
      05-12-2010
On Wed, 12 May 2010 11:18:49 -0400
Eric Sosman <> wrote:
>> If you change unsigned int to unsigned char then you get -2 as expected as
>> the result.

>
> Right again.
>
> Remember, every expression in C has a single type, fixed at
>compile time and immutable thereafter. In particular, the type


Ah ok. That never occured to me. I always just treated the question
mark operator as a version of "if".

Thanks for everyones help.

> By the way, if you crank up gcc's warning levels it will tell
>you "warning: signed and unsigned type in conditional expression."
>I think it's good practice to crank up the warnings as high as your
>code can stand -- and even if you don't routinely put them to the
>max, you should *definitely* do so when confronted with a mystery.


Good idea.

B2003


 
Reply With Quote
 
lawrence.jones@siemens.com
Guest
Posts: n/a
 
      05-12-2010
d wrote:
>
> Can someone tell me whats going on here. I'm using gcc 4.3.3 in linux.
> Have I missed something obvious in the code snippet below or is there some
> odd casting bug going on with gcc?

[...]
> printf("%f\n",(double)(1 ? (int)d : (unsigned int)1));


Neither. What's happening is that the value of d is converted to an int
(-2), but then that value is converted to unsigned int (because the
result of the ?: operator has the type that results from applying the
usual arithmetic conversions to the second and third operands), which
turns the small negative value into a large unsigned value, which is
then converted to double.
--
Larry Jones

Sometimes I think the surest sign that intelligent life exists elsewhere
in the universe is that none of it has tried to contact us. -- Calvin
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      05-12-2010
d wrote:

> double d = -2.345;
> printf("%f\n",(double)(1 ? (int)d : (unsigned int)1));


What you want (if you want something like this at all, which I doubt) is

printf("%f\n", 1 ? (double)(int)d : (double)(unsigned int)1 );

That way, each half is first cast to its desired type, and then
_immediately_ to double, without going through another conversion
required by the use of ?:. The type of the entire ?: operation will then
be double, of course.

More interesting than a correct way to do something iffy, though, is the
question why you would want to do something this iffy in the first
place. It doesn't seem like a natural thing to do, to me. What are your
_actual_ requirements, and why can't you just do

printf("%f\n", (double) (1? (int)d :1) );

Richard
 
Reply With Quote
 
bart.c
Guest
Posts: n/a
 
      05-13-2010

"Eric Sosman" <> wrote in message
news:hsegu2$6qa$...
> On 5/12/2010 10:08 AM, d wrote:


>> double d = -2.345;
>> printf("%f\n",(double)(1 ? (int)d : (unsigned int)1));
>> }
>> $ cc t.c
>> $ ./a.out
>> 4294967294.000000


> Remember, every expression in C has a single type, fixed at
> compile time and immutable thereafter. In particular, the type
> of `x?y:z' is one type, not "sometimes the type of y and sometimes
> the type of z, depending on x." So, what happens when y and z
> start out as different types? The same thing that happens when
> you compute `y+z' or `y>z' or pretty much anything else: The "usual
> arithmetic conversions" are performed, and the result has the type
> that those conversions produce. So, what's the type of `-2 + 1u'?
> And what's the type of `1 ? -2 : 1u'?


Interesting. What's the type of the ?: expression in these two examples:

int a,b,c,d;
float x,y;

d=(c?a =b);
y=(c?a =b);

(This works as expected in my gcc.)

--
Bartc

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      05-13-2010
On 5/13/2010 8:28 AM, bart.c wrote:
>
> "Eric Sosman" <> wrote in message
> news:hsegu2$6qa$...
> [...] The same thing that happens when
>> you compute `y+z' or `y>z' or pretty much anything else: The "usual
>> arithmetic conversions" are performed, and the result has the type
>> that those conversions produce. So, what's the type of `-2 + 1u'?
>> And what's the type of `1 ? -2 : 1u'?

>
> Interesting. What's the type of the ?: expression in these two examples:
>
> int a,b,c,d;
> float x,y;
>
> d=(c?a =b);
> y=(c?a =b);


I see no expressions here at all, just constraint violations
the compiler is required to complain about.

What are you really asking?

--
Eric Sosman
lid
 
Reply With Quote
 
bart.c
Guest
Posts: n/a
 
      05-13-2010

"Eric Sosman" <> wrote in message
news:hsgtgs$cop$...
> On 5/13/2010 8:28 AM, bart.c wrote:
>>
>> "Eric Sosman" <> wrote in message
>> news:hsegu2$6qa$...
>> [...] The same thing that happens when
>>> you compute `y+z' or `y>z' or pretty much anything else: The "usual
>>> arithmetic conversions" are performed, and the result has the type
>>> that those conversions produce. So, what's the type of `-2 + 1u'?
>>> And what's the type of `1 ? -2 : 1u'?

>>
>> Interesting. What's the type of the ?: expression in these two examples:
>>
>> int a,b,c,d;
>> float x,y;
>>
>> d=(c?a =b);
>> y=(c?a =b);

>
> I see no expressions here at all, just constraint violations
> the compiler is required to complain about.


Just pointing out that ?: expressions involving lvalues might have different
rules (for determining the common type). Here's a more practical example:

int a=0,b,c=1;
char ch;

b = ++(c?ch:a);

(This is non-standard, nevertheless someone has implemented it, and must
have discovered that treating ?: as you describe wouldn't have worked.)

--
Bartc

 
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
*bug* *bug* *bug* David Raleigh Arnold Firefox 12 04-02-2007 03:13 AM
ASP.NET Login control bug or SQL 2005 bug? RedEye ASP .Net 2 12-13-2005 10:57 AM
Re: BUG? OR NOT A BUG? John ASP .Net 2 09-21-2005 10:31 AM
Bug Parade Bug 4953793 Michel Joly de Lotbiniere Java 4 12-02-2003 05:05 AM
how to report bug to g++ ? got a bug and fixed up source code DarkSpy C++ 4 06-27-2003 09:05 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57