There is such code:
int i = 5; printf("%d %d %d", i++, i++, i++); Conclusion: 7 6 5
Why is this conclusion happening? Said related to a variable number of arguments.
There is such code:
int i = 5; printf("%d %d %d", i++, i++, i++); Conclusion: 7 6 5
Why is this conclusion happening? Said related to a variable number of arguments.
A very simple explanation is that since the standard says nothing about the order in which the function arguments are calculated, the compiler does this as it sees fit. So you get 7 6 5 , you can get 5 6 7 or, say, 6 5 7 ... You get what is called uncertain behavior .
The explanation is more precise, but also more complicated - read the literature about the points of the sequence ... For example, here or here .
f(++k, ++k) is "undefined behavior" in C, and "unspecified behavior" after c ++ 17 . 2- After the actions related to% n in printf, there is a "sequence point" in c99 . True c ++k does not help. - jfsi= ++i became definite), but if we consider that they were caused by defectiveness of the entire model sequencing in C ++ 98, then we can say that C and C ++ went in diametrically opposite ways from the very beginning. Therefore, what happens in this area in C ++ has nothing to do with C. The semantics ++i in C ++ has practically nothing to do with the semantics ++i in C. - AnT7 6 5 il 5 6 7 would be unspecified behavior. In this case, we have an indefinite behavior, which is a fundamentally different phenomenon. - AnTFirstly, the question is not related to the variable number of parameters for the printf function at all.
Secondly, the behavior in your example is undefined (undefined behavior), because the multiple side effects affecting the variable i (increasing the value of i by one) are in no way ordered relative to each other.
Please note that this phenomenon cannot be explained by the uncertainty of the order in which the function arguments are calculated . Similar explanations are a popular and quite common misconception. In fact, it is the uncertainty of order, as such, has nothing to do with the emergence of uncertain behavior in this case. If to be expressed "on fingers", then it is more important that the calculations of independent expression-arguments are not isolated from each other and can be "intertwined" with each other as you like.
And, for example, in this code
int foo(int *p) { return (*p)++; } int i = 5; printf("%d %d %d", foo(&i), foo(&i), foo(&i)); The order of calculating the arguments is also not specified, but (!) there is no undefined behavior here. Behavior is simply not specified. Informally, the reason for this is precisely that the execution of function bodies in two independent calls cannot be "intertwined" - they are ordered relative to each other, even if in this case it is unknown how.
Pay attention to this subtlety: in your example, the side effects are not ordered at all , but in my example they are ordered in an unspecified way . These are different things. In your case, the behavior is not defined, in my example - the behavior is not specified.
It is in my example that you can get 5 6 7 , and 7 6 5 , etc. Behavior is not specified, but limited to a clearly defined set of options. In your own code, absolutely anything can happen, up to the compiler's failure to compile your code or to the textbook “formatting a hard disk” and launching even more textbook “nasal demons”.
gcc -O3 on Linux X86_64 takes a different view, as seen in movl $5, %r8d; movl $6, %ecx; movl $7, %edx movl $5, %r8d; movl $6, %ecx; movl $7, %edx movl $5, %r8d; movl $6, %ecx; movl $7, %edx before calling printf (especially considering that i = 5 simply not in the generated code) - avpSource: https://ru.stackoverflow.com/questions/629916/
All Articles
va_arg. - jfs