Thread: preprocessor output

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    17

    preprocessor output

    hi,
    Can anyone explain about the output of the following program ???
    insert
    Code:
    #define CUBE(x) (x*x*x)
    
    int main()
    {
       int a,b=3;
       a=CUBE(b++);
       printf("%d %d",a,b);
    
    }
    When i execute this program the output is 27,6....i dont know why b is getting incremented every time.

    Bcos when we call the macro....

    at that time b's value will be b++ is as equal as b=b+1; so b's value will be incremented to 4

    so the macro should yield 4*4*4=64

    But the results are strange can anyone please explain me how the program behaves ????

    Regards,
    rohit

  2. #2
    Registered User
    Join Date
    Aug 2008
    Posts
    15
    Your code looks like this after preprocessing.

    Code:
    int main()
    {
       int a,b=3;
       a =(b++ * b++ * b++); /* CUBE(b++) gets replaced.      
       printf("%d %d",a,b);
    
    }
    Value for a is calculated as below with the b value as 3, since its post increment operator.

    Code:
    a =(3*3*3);
    and then b is incremented 3 times. i.e, 4,5,6

    So finally, when you print the result will be 27,6.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    After preprocessing, your program becomes:
    Code:
    int main()
    {
       int a,b=3;
       a=(b++*b++*b++);
       printf("%d %d",a,b);
    
    }
    Macros are not functions; they do dumb text replacement.

    EDIT:
    Quote Originally Posted by patil.vishwa
    Value for a is calculated as below with the b value as 3, since its post increment operator.
    Actually, the expression results in undefined behaviour since b is read and changed multiple times within the same sequence point.
    Last edited by laserlight; 09-03-2008 at 11:50 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    >> and then b is incremented 3 times. i.e, 4,5,6

    Actually, if it worked as you thought it did (see laserlight's post), then the result would be,
    3 * 4 * 5 = 60

    Since it's post-increment, ie use the value and then increment. Still, not sure how you got 27 either, 4 * 5 * 6 = 120.

    Such that,
    Code:
    int b = 3;
    int stepOne = b++;   /* = 3, THEN b is incremented, such that b = 4 */
    int stepTwo = b++;   /* = 4, THEN b is incremented, such that b = 5 */
    int stepThree = b++; /* = 5, THEN b is incremented, such that b = 6 */
    
    printf("%d,%d\n", (stepOne * stepTwo * stepThree), b);
    Would output 60,6. Which is well defined behaviour, with several sequence points (one for each step).
    Last edited by zacs7; 09-04-2008 at 03:02 AM. Reason: Hmm!

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by rohit_second View Post
    But the results are strange can anyone please explain me how the program behaves ????
    Aside from the fact that b++ * b++ * b++ is undefined, you can actually find out what your code looks like AFTER the expansion of macros and inclusion of include files - it is sometimes quite a useful thing to do. Most compilers use an option -E or /E to output the preprocessed source code - usually you will need a -o or /o to tell the compiler where you want to output this file (it is commonly called .i, so "gcc -E myprog.c -o myprog.i" would be how you do this in gcc, for example).

    Even if it doesn't actually answer your question here (because the actual answer has to do with undefined behaviour, and that is always impossible to answer categorically), it will be good practice to understand how to read pre-processed C or C++ code. Sometimes when you have a "missing semicolon" or some such, it is caused by a macro expansion that you didn't fully understand what it did.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Aug 2008
    Posts
    15
    Quote Originally Posted by matsp View Post
    Aside from the fact that b++ * b++ * b++ is undefined, you can actually find out what your code looks like AFTER the expansion of macros and inclusion of include files.
    --
    Mats
    I'd done this already, see it looks as i mentioned earlier...

    Code:
    int main()
    {
       int a,b=3;
       a= ( ( b ++ ) * ( b ++ ) * ( b ++ ) );
       printf("%d %d \n",a,b);
    
    }
    The same program produces wierd result when pre increment operator is used.
    Last edited by patil.vishwa; 09-04-2008 at 05:06 AM.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by patil.vishwa View Post
    I'd done this already, see it looks as i mentioned earlier...

    Code:
    int main()
    {
       int a,b=3;
       a= ( ( b ++ ) * ( b ++ ) * ( b ++ ) );
       printf("%d %d \n",a,b);
    
    }
    The same program produces wierd result when pre increment operator is used.
    Yes, using ++, -- (and +=, -= and such) more than once on the same variable in the same expression will almost always cause "weird" output. This is because the C standard actually specifically says that updates to a variable should only ever be done ONCE between two sequence points [sequence points are places where calculations are completed, so usually the same as a statement or within the () of a function argument list]. Anything that does otherwise is "undefined behaviour", which essentially means that it can not be guaranteed in any way - it may produce the correct result, something "nearly correct", it may also produce completely silly results (e.g. you expect a value around 50, but it produces 11290823 because of some side-effect of one of the calculations), or even crash.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed