0

What happens when we use multiple assignments to the same variable within a single printf? Of course it is an unspecified behaviour. But how does gcc behave? (I hope the behaviour is independant of gcc version)

Examples:

int a=30;  
printf("%d %d %d %d",a=12,a++,a=a+1); 

The above code snippet gave output
12 31 12

a=30;  
printf(" %d %d %d %d ",a--,a=12,a++,a=a+1); 

gave output
12 11 31 11

a=30,b=100;  
printf("%d %d %d %d  %d %d %d %d ",a=12,b++,a++,a=200,b=20,a++,a=a+2,b=40); 

gave output
12 20 200 12 21 32 12 21

a=30,b=100;  
printf("<outside>(%d chars for inside printf) %d %d %d %d ",  
printf("<inside> %d %d %d %d ",a=12,b++,a++,a=200),b=20,a++,a=a+2,b=40);  

gave output
12 20 200 12 (22 chars for inside printf) 21 32 12 21

The explanation we found is evaluation is done right to left, assignments take final value of each variable and other expressions seem to be pushed to the stack? Is this a good explanation or is it something else going on there?

(NB: gcc may be using some registers instead of stack. But the behaviour seems same)

My teacher gave an explanation that there is a pipe for each variable and when %d flushes the pipe, its contents are not lost. So when again that variable is taken by another %d, the old content of the pipe is again used.

Notes: Pre-increment and Pre-decrement are treated like assignment whereas post-increment and post-decrement are treated like 'other expressions'.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Cyriac Antony
  • 386
  • 1
  • 3
  • 13
  • Do not run to be a hacker. Read the books and forums first. About variables changed in one line we had here hundreds posts – 0___________ Sep 22 '17 at 07:25
  • Why don't you disassemble each variant, run it under your debugger and tell us? – Martin James Sep 22 '17 at 09:23
  • When using a variable number of parameters, like `printf`, some compilers will push parameters to the stack right-to-left, so the first parameter always appears at the top. Makes it slightly easier for the called function to find it. Other compilers might pass some parameters in registers (left-to-right), depending on the types and number of parameters. Nothing you should rely on. – Bo Persson Sep 22 '17 at 10:49

2 Answers2

3

No, it is not unspecified, it is undefined behavior.

You are essentially trying to modify the value of a single variable more than once without a sequence point in between. That's where it hit UB.

FWIW, there is no guarantee that function arguments are passed using stack. they can very well be passed via registers. Moreover, there is not inherit concept of "stack" and "heap" etc. mentioned in the C standard, so the premise of the conclusion itself is not universally valid.

Moral of the story: Enable compiler warnings and treat warnings as errors, any decent compiler should refuse to compile a code like above.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

It is a undefined behavior and undefined behavior means anything can happens.

According to this blog :

The C FAQ defines “undefined behavior” like this:

Anything at all can happen; the Standard imposes no requirements. The program may fail to compile, or it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.

I have compiled your program in GCC on Linux platform using gcc -Wall flag, I got following warning:

seq.c:6:32: warning: operation on ‘a’ may be undefined [-Wsequence-point]
  printf("%d %d %d\n",a=12,a++,a=a+1);
                                ^
seq.c:6:32: warning: operation on ‘a’ may be undefined [-Wsequence-point]

In which order it will evaluate , that is not defined in C standard.

Jayesh
  • 4,755
  • 9
  • 32
  • 62