The parameters processing order of a cdecl function

64 views Asked by At

As far as I can tell, a cdecl function pushes its parameters onto stack from right to left. However,

int n = 0;
printf("%d %d", n=8, n); // Output: 8 8

I expect it to output 8 0, as I thought it calculates parameters by the order by which it pushes parameters--from right to left . I tried the code on TDM-GCC 32bit/64bit, GCC x64, MSVC x86/x64 and clang x64, and got the same result.

So I concluded that a cdecl function calculates its parameters before pushing them onto stack, and the two processes proceed in reverse order.

However,

int n = 0;
printf("%d %d", n=8, n=0); // Output: 8 8

I do NOT understand it.

2

There are 2 answers

1
gulpr On BEST ANSWER

The order of evaluation is not defined in C language.

Your example prints 8 8 most likely because the compiler has optimized out the assignment and it could do it as it is UB.

The following example will show different behaviour if this optimization cannot be done (and it is up to the compiler as it is UB) .

int main(void)
{
    volatile int n = 0;
    int m = 0;
    printf("n= %d %d\n", n = 8, n);
    printf("m= %d %d\n", m = 8, m);
}

https://godbolt.org/z/crKbs1hjE

3
lechatbleu On

In C, the order in which function arguments are evaluated is unspecified. This means the compiler is free to evaluate arguments in any order it chooses. This is a crucial point to understand. The order in which arguments are pushed onto the stack (in the case of cdecl calling convention) is not necessarily the same as the order in which they are evaluated.

printf("%d %d", n=8, n);

Here, since the order of evaluation of arguments is unspecified, both n=8 and n might be evaluated in any order. Most compilers evaluate function arguments from left to right, but this is not guaranteed by the C standard. In your case, it seems that n=8 is evaluated first, setting n to 8. Then, when n is evaluated, it is already 8. Hence, you see 8 8.

printf("%d %d", n=8, n=0);

This case is similar to the first one. The unspecified order of argument evaluation leads to both assignments potentially being evaluated in any order. If n=8 is evaluated first, n is set to 8, and then n=0 might not change the output because printf might have already fetched the value of n for the first %d. This behavior can vary across different compilers and even different versions of the same compiler.