C awesomeness (not)


The_C_Programming_Language_logo.svg

Few days ago I was asked question what would be the output of this code:

#include <stdio.h>
int main()
{
      int a = 5;

      printf("%d %d %d %d\n",a++,a++,++a,a++);

      return 0;
}

Nothing special, right? But C standard do not specify how printf evaluates it’s parameters, so it’s left up to the C compiler and here the fun part starts.

Old C compilers would be a bit more predictable as they would start evaluating from the top of the stack to the bottom i.e. right to left, but the new ones heavy optimize and try to execute some instructions in parallel, so the only certain thing is that at the printf “;” point of synchronization “a” would be incremented 4 time, but nobody knows in what order.

Compiled with GCC/Code Blocks the output is:

Screenshot from 2019-02-20 11-46-45

Again nobody guarantee that if you re-compile on different computer /CPU the result will be same!

Even changing the code with one more line like enter the value of a with scanf leads to different result:

Screenshot from 2019-02-20 11-47-47

So good practice will be to avoid any calculations inside printf and to search logic there. Do these separately where compiler has to stick to C standard and rules.

 

1 Comment (+add yours?)

  1. Bartek
    Mar 07, 2019 @ 14:03:45

    Of course its nothing special – its just undefined behaviour as described in standard.
    You do mention that the order of function call argument evaluation its not specified (perhaps adding a link to the article about sequence points could be beneficial to some readers), but after that you claim that “one should avoid calculations inside printf” which is simply misleading.
    1. Its not limited to printf – it applies to any function call
    2. Its not about calculations, its about expressions with side-effects
    3. Its not limited to function calls –

    This is perfectly safe (assuming correct format string):
    printf(“…”, a+1, b-2, a*7);

    x = a++ – ++a; // this is UB and must be avoided

    Reply

Leave a Reply to Bartek Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: