简体   繁体   中英

Function passing arguments in reverse

Here is my function:

void abc(char  *def, unsigned int w, unsigned int x, unsigned int y, unsigned int z)
{
   printf("val 1 : %d\n", w);
   printf("val 2 : %d\n", x);
   printf("val 3 : %d\n", y);
   printf("val 4 : %d\n", z);
}

and here is where I call this function:

unsigned int exp[4] = { 1, 2, 3, 4 };
unsigned short count = 0;
abc(anyarray, exp[count++], exp[count++], exp[count++], exp[count++]);

and here is the output that I expect:

val1 : 1
val2 : 2
val3 : 3
val4 : 4

but what I get is completely reverse of it:

val1 : 4
val2 : 3
val3 : 2
val4 : 1

I don't know why? Any help would be appreciated.

From standard docs, 5.4

Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified58) Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.

An example from the Standard docs itself,

i = v[i ++]; / / the behavior is undefined

And it is for the very same reason that

abc(anyarray, exp[count++], exp[count++], exp[count++], exp[count++]); is undefined..

You should not use the ++ operator, operating on the same variable, more than once in the same statement. The order in which the operation will be performed is not defined.

Try:

abc(anyarray, exp[count], exp[count+1], exp[count+2], exp[count+3]);  
count += 4; 

您通过在没有插入序列点的情况下多次修改count来调用未定义的行为。

You are counting on the parameters being evaluated left to right. You can't make any assumptions about the order that they're evaluated. In this case, it looks like the compiler is evaluating them right-to-left.

Also, you may want to look up sequence points, because it may be that you shouldn't use the ++ operator in this way.

abc(anyarray, exp[count++], exp[count++], exp[count++], exp[count++]);

The order of evaluation of arguments of abc is unspecified but the expression invokes undefined behaviour because you are trying to modify a variable count more than once between two sequence points.

Furthermore using incorrect format specifier in printf() also invokes UB. Please make sure you have used correct format specifiers(ie %u for unsigned int ) in printf() .

You got this because you called adb(exp,a,b,c,d) according to your problem, but during call of function d is pushed first on stack and then c ,b relatively. As you passed exp[count++] at last argument which will process first to push over stack means 1 is pushed first then 2 then 3 then 4. And in called function pop performed so you get w=4 x=3 y=2 z=1 that's it.

This is because of the calling convention. In _cdecl, the default calling convention for c/c++ programs (according to microsoft), the parameters are passed on the stack to the function in reverse order. Because of this, the parameters are also evaluated in reverse order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM