#include<stdio.h>
main()
{
int a=10;
printf("%d %d %d\n",a=10,a=20,a=30);
}

o/p: 10 10 10.
Here, the latest value is updated and printed as the expression statements separated by commas in funtions are evaluted from right to left.

But, in below program by using global variable or static variable why the updated value is not printed??

#include<stdio.h>
int a=10;
main()
{
printf("%d %d %d\n",a=10,a=20,a=30);
}

o/p: 10 20 30.

For static variable,

#include<stdio.h>
main()
{
static int a=10;
printf("%d %d %d\n",a=10,a=20,a=30);
}

o/p: 10 20 30

Dani AI

Generated

The differing outputs are not about storage duration (automatic vs global) so much as about evaluation order and unsequenced side effects. correctly identified that the code modifies the same object multiple times in one full expression, and the C standard leaves the result undefined. also correctly noted that the commas in a function call separate arguments (they are not the comma operator) and do not impose a left-to-right sequencing of those subexpressions.

The formal rule is in the C standard: if a side effect on a scalar object is unsequenced relative to another side effect or a value computation using that object, the behavior is undefined (see the C11 draft, section 6.5). Compilers are free to evaluate arguments in any order and to implement temporaries, registers, or memory stores differently; that is why , and saw different results on different builds and targets. Inspecting the generated assembly (gcc -S) will show these implementation choices.

Practical, safe fixes:

  • Do not modify the same variable multiple times inside a single expression. Split assignments into separate statements or capture intermediate results into temporaries before calling the function.
  • Example pattern to make behavior explicit:
int x = (a = 10);
int y = (a = 20);
int z = (a = 30);
printf("%d %d %d\n", x, y, z);
  • Use compiler warnings and tools (static analyzers, clang-tidy/cppcheck) and examine generated assembly if curious about why a particular compiler produced an observed output.

Final note: because the original construct produces undefined behavior, any observed output (including the variations you reported) is compatible with the standard and should not be relied upon. For the definitive language, refer to the C11 draft: C11 draft — n1570 (section 6.5).

Recommended Answers

All 6 Replies

I suspect it has something to do with how your compiler handles the different types of variables. Both static and global variables remain intact for the entire run of the program. On the other hand local variables are allocated on the stack and remain intact only during the current execution of the function in which it is defined.

That being said Microsoft Visual returns the amount assigned in the first a= for all occurances of a in the printf:

int a=10;
printf("%d,%d,%d",a=5,a=10,a=15);

Each of the three types of variables returns 5,5,5.

jnawrocki,

I'm using GCC complier in LINUX operating sys. I know the explanation what u gave,but why its not updating with latest values for global variables ..

jnawrocki,

I'm using GCC complier in LINUX operating sys. I know the explanation what u gave,but why its not updating with latest values for global variables ..

I've just compiled all the examples you gave, and the outputs are 10 20 30.


You'd expect the output to be 10 20 30, since a= is an assignment.

By the way, it's advised not to use global variables in C, or C++.

(p.s the code brackets help alot :) )

printf("%d %d %d\n",a=10,a=20,a=30);

> expression statements separated by commas

This is not a comma expression - this is an argument list. They look very similar, but they are really different creatures (think about this: the comma expression yields just one value). In the argument list case there's no guarantee in which order the arguments are evaluated.

Its because when gcc compiles the code, it first evaluates the equations then pushes the registers for the function call. In the first example with the local variable it evaluates the expressions a=10,a=20, and a=30 into the same location in the stack, then it pushes that location in the stack 3 times. In the second example with the global variable, it evaluates into the global variable and then moves the global's value into separate registers. After the evaluation, it then pushes the individual registers into the stack for the printf call.

You can compile the progams with the -S flag and look at the .s (assembler) files to see exactly how it works.

printf("%d %d %d\n",a=10,a=20,a=30);

The language standard indicates this statement has "undefined behavior" because the variable a is changed more than once between two squence points (start of the statement and before the function call but after all the parameters have been evaluated). In this case, there are three assignment operators with variable a as an lvalue. So any result from this statement and the rest of the program is correct behavior according to the language standard. This would include printing anything or nothing from that statement or stopping execution completely.

What life time or scope for the variable a does not change that it has undefined behavior. So yes, changing those things and getting different results is allowed by the language standard.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.