Bug in GCC?

Discussion in 'C Programming' started by boltar2003@boltar.world, May 12, 2010.

  1. Guest

    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
    , May 12, 2010
    #1
    1. Advertising

  2. 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
    Pramod Subramanyan, May 12, 2010
    #2
    1. Advertising

  3. On May 12, 11:08 am, 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
    William Hughes, May 12, 2010
    #3
  4. Eric Sosman Guest

    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
    Eric Sosman, May 12, 2010
    #4
  5. Guest

    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
    , May 12, 2010
    #5
  6. Guest

    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
    , May 12, 2010
    #6
  7. Richard Bos Guest

    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
    Richard Bos, May 12, 2010
    #7
  8. bart.c Guest

    "Eric Sosman" <> wrote in message
    news:hsegu2$6qa$-september.org...
    > 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:x =b);
    y=(c?a:x =b);

    (This works as expected in my gcc.)

    --
    Bartc
    bart.c, May 13, 2010
    #8
  9. Eric Sosman Guest

    On 5/13/2010 8:28 AM, bart.c wrote:
    >
    > "Eric Sosman" <> wrote in message
    > news:hsegu2$6qa$-september.org...
    > [...] 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:x =b);
    > y=(c?a:x =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
    Eric Sosman, May 13, 2010
    #9
  10. bart.c Guest

    "Eric Sosman" <> wrote in message
    news:hsgtgs$cop$-september.org...
    > On 5/13/2010 8:28 AM, bart.c wrote:
    >>
    >> "Eric Sosman" <> wrote in message
    >> news:hsegu2$6qa$-september.org...
    >> [...] 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:x =b);
    >> y=(c?a:x =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
    bart.c, May 13, 2010
    #10
  11. Eric Sosman Guest

    On 5/13/2010 9:52 AM, bart.c wrote:
    >
    > "Eric Sosman" <> wrote in message
    > news:hsgtgs$cop$-september.org...
    >> On 5/13/2010 8:28 AM, bart.c wrote:
    >>>
    >>> "Eric Sosman" <> wrote in message
    >>> news:hsegu2$6qa$-september.org...
    >>> [...] 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:x =b);
    >>> y=(c?a:x =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).


    They do not. If you think you've pointed out a difference,
    you think wrongly.

    > 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.)


    As you point out, your example is not C. This being comp.lang.c
    and not comp.lang.plxlii, I wrote about the rules for determining the
    types of C expressions. In fact, my text started "Remember, every
    expression *in C* [emphasis added] has a single type..."

    --
    Eric Sosman
    lid
    Eric Sosman, May 13, 2010
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    8
    Views:
    414
  2. Kevin P. Fleming

    C99 structure initialization in gcc-2.95.3 vs gcc-3.3.1

    Kevin P. Fleming, Nov 6, 2003, in forum: C Programming
    Replies:
    2
    Views:
    632
    Kevin P. Fleming
    Nov 6, 2003
  3. Replies:
    5
    Views:
    350
    Nathan Addy
    Sep 17, 2005
  4. ashnin

    GCC 3.4.3 and GCC 4.1.2

    ashnin, Jul 7, 2008, in forum: C++
    Replies:
    1
    Views:
    502
    Michael DOUBEZ
    Jul 7, 2008
  5. kas
    Replies:
    1
    Views:
    309
    red floyd
    Apr 22, 2010
Loading...

Share This Page