union, ternary operator, and C. What a mess!

Discussion in 'C Programming' started by Paul E Johnson, Oct 17, 2003.

  1. Dear friends in C:

    I'm completely baffled by this problem I have with
    printf statements and conditional operators in C.
    I'm using gcc-3.3.

    I have a project where the rarely used Union type
    is called for! Incredible, but true.

    union mixed
    {
    long unsigned int i;
    double f;
    } newMem;


    It is no trouble to retrieve the values with newMem.i or newMem.f.
    However, I want to make the choice between the two automatic by writing a
    macro like this, which keys on the value of a variable "Stochastic":

    #define UMACRO(var) ((Stochastic) ? var.i : var.f )

    So if Stochastic ==1 then I want to get back newMem.i,
    otherwise I want newMem.f.

    I get this psychotic behavior. WHen the macro UMACRO is in a
    printf statement, things go completely berserk!

    Here's a code snip:

    printf("newMem = %lu \n", newMem.i);
    printf("Stochastic=%d, UMACRO = %lu Stochastic = %d \n",Stochastic,
    UMACRO(newMem), Stochastic);
    {
    long unsigned int testval = UMACRO(newMem);
    printf("testval %lu\n", testval);
    }


    And here's the output it produces when Stochastic==1 and
    newMem.i = 97:

    newMem = 97
    Stochastic=1, UMACRO = 0 Stochastic = 1079525376
    testval 97

    When you look at the ouptut in line 2, you figure UMACRO
    does not work at all, and it does something horrible affect
    the printout of the second Stochastic in that line. However,
    note the 3rd line, which is produced by first retrieving the value from
    the union and then printing it out. That is correct.


    I was thinking that the problem is the pre-processor, but
    here is the output from gcc -E, which appears as expected.

    printf("newMem = %lu \n", newMem.i);
    printf("Stochastic=%d, UMACRO = %lu Stochastic = %d \n",Stochastic,
    ((Stochastic)?newMem.i:newMem.f ), Stochastic);
    {long unsigned int testval = ((Stochastic)?newMem.i:newMem.f );
    printf("testval %lu\n", testval);}

    So maybe the ternary conditional is not working in the
    right hand side of the printf? Is that a known thing? And
    why does it make the output of the second Stochastic in line 2 turn into
    crapola 1079525376.

    ???

    --
    Paul E. Johnson email:
    Dept. of Political Science http://lark.cc.ukans.edu/~pauljohn
     
    Paul E Johnson, Oct 17, 2003
    #1
    1. Advertising

  2. Paul E Johnson

    xarax Guest

    "Paul E Johnson" <> wrote in message
    news:p...
    > Dear friends in C:
    >
    > I'm completely baffled by this problem I have with
    > printf statements and conditional operators in C.
    > I'm using gcc-3.3.
    >
    > I have a project where the rarely used Union type
    > is called for! Incredible, but true.
    >
    > union mixed
    > {
    > long unsigned int i;
    > double f;
    > } newMem;
    >
    >
    > It is no trouble to retrieve the values with newMem.i or newMem.f.
    > However, I want to make the choice between the two automatic by writing a
    > macro like this, which keys on the value of a variable "Stochastic":
    >
    > #define UMACRO(var) ((Stochastic) ? var.i : var.f )
    >
    > So if Stochastic ==1 then I want to get back newMem.i,
    > otherwise I want newMem.f.
    >
    > I get this psychotic behavior. WHen the macro UMACRO is in a
    > printf statement, things go completely berserk!
    >
    > Here's a code snip:
    >
    > printf("newMem = %lu \n", newMem.i);
    > printf("Stochastic=%d, UMACRO = %lu Stochastic = %d \n",Stochastic,
    > UMACRO(newMem), Stochastic);
    > {
    > long unsigned int testval = UMACRO(newMem);
    > printf("testval %lu\n", testval);
    > }
    >
    >
    > And here's the output it produces when Stochastic==1 and
    > newMem.i = 97:
    >
    > newMem = 97
    > Stochastic=1, UMACRO = 0 Stochastic = 1079525376
    > testval 97
    >
    > When you look at the ouptut in line 2, you figure UMACRO
    > does not work at all, and it does something horrible affect
    > the printout of the second Stochastic in that line. However,
    > note the 3rd line, which is produced by first retrieving the value from
    > the union and then printing it out. That is correct.
    >
    >
    > I was thinking that the problem is the pre-processor, but
    > here is the output from gcc -E, which appears as expected.
    >
    > printf("newMem = %lu \n", newMem.i);
    > printf("Stochastic=%d, UMACRO = %lu Stochastic = %d \n",Stochastic,
    > ((Stochastic)?newMem.i:newMem.f ), Stochastic);
    > {long unsigned int testval = ((Stochastic)?newMem.i:newMem.f );
    > printf("testval %lu\n", testval);}
    >
    > So maybe the ternary conditional is not working in the
    > right hand side of the printf? Is that a known thing? And
    > why does it make the output of the second Stochastic in line 2 turn into
    > crapola 1079525376.


    This is likely caused by the different sizes of
    "long unsigned int" vs. "double".

    I suggest moving the (Stochastic)? test to an if(Stochastic) statement.
    Then use hard-coded references to newMem.i or newMem.f in the
    appropriate "then" or "else" part of the if() statement.

    if(Stochastic)
    {
    printf(..whatever..,newMem.i);
    }
    else
    {
    printf(..whatever..,newMem.f);
    }

    HTH
     
    xarax, Oct 17, 2003
    #2
    1. Advertising

  3. Paul E Johnson

    Ed Morton Guest

    Paul E Johnson wrote:

    > Dear friends in C:
    >
    > I'm completely baffled by this problem I have with
    > printf statements and conditional operators in C.
    > I'm using gcc-3.3.
    >
    > I have a project where the rarely used Union type
    > is called for! Incredible, but true.


    Rarely used? I use them all the time...

    <snip>


    > I was thinking that the problem is the pre-processor, but
    > here is the output from gcc -E, which appears as expected.


    Didn't it also give you a warning about the third printf? If not, try it
    again with "-Wall" set.

    > printf("newMem = %lu \n", newMem.i);
    > printf("Stochastic=%d, UMACRO = %lu Stochastic = %d \n",Stochastic,
    > ((Stochastic)?newMem.i:newMem.f ), Stochastic);
    > {long unsigned int testval = ((Stochastic)?newMem.i:newMem.f );
    > printf("testval %lu\n", testval);}
    >
    > So maybe the ternary conditional is not working in the
    > right hand side of the printf? Is that a known thing? And
    > why does it make the output of the second Stochastic in line 2 turn into
    > crapola 1079525376.
    >
    > ???
    >


    Your macro is fine, it's your printf fomatting that's bad. Try using %e
    (for "double") instead of %lu (for "long...") in UMACRO= part and you'll
    see the difference.

    Ed.
     
    Ed Morton, Oct 17, 2003
    #3
  4. Paul E Johnson

    Ed Morton Guest

    Ed Morton wrote:


    > Didn't it also give you a warning about the third printf?

    s/third/second/
     
    Ed Morton, Oct 17, 2003
    #4
    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. Matt Garman
    Replies:
    1
    Views:
    677
    Matt Garman
    Apr 25, 2004
  2. Roger Leigh

    ternary operator and ostreams

    Roger Leigh, Jan 16, 2004, in forum: C++
    Replies:
    6
    Views:
    670
    Roger Leigh
    Jan 19, 2004
  3. Paul E Johnson
    Replies:
    2
    Views:
    584
    Christian Bau
    Oct 17, 2003
  4. zipher
    Replies:
    2
    Views:
    364
    Gerrit
    Sep 13, 2004
  5. Udo A. Steinberg

    Ternary operator and memory access

    Udo A. Steinberg, Aug 7, 2006, in forum: C Programming
    Replies:
    20
    Views:
    571
    Keith Thompson
    Aug 8, 2006
Loading...

Share This Page