function parameter evaluation order

后端 未结 5 1881
攒了一身酷
攒了一身酷 2020-11-22 07:37

In C and C++, is there a fixed order for evaluation of parameter to the function? I mean, what do the standards say? Is it left-to-right or right-to-left<

5条回答
  •  礼貌的吻别
    2020-11-22 07:53

    As far as I know, the function printf has an exception here.

    For an ordinary function foo, the order of evaluation of foo(bar(x++), baz(++x)) is undefined. Correct! However printf, being an ellipsis function has a somewhat more definite order of evaluation.

    The printf in the standard library, in fact, has no information about the number of arguments that has been sent to. It just tries to figure out the number of variables from the string placeholders; namely, from the number of percent operators (%) in the string. The C compiler starts pushing arguments from the very right towards left; and the address of the string is passed as a last argument. Having no exact information about the number of arguments, printf evaluates the last address (the string) and starts replacing the %'s (from left to right) with values of the corresponding addresses in the stack. That is, for a printf like below;

    {
        int x = 0;
        printf("%d %d %f\n", foo(x), bar(x++), baz(++x));
    }
    

    The order of evaluation is:

    1. x is incremented by 1,
    2. function baz is called with x = 1; return value is pushed to the stack,
    3. function bar is called with x = 1; return value is pushed to the stack,
    4. x is incremented by 1,
    5. function foo is called with x = 2; return value is pushed to the stack,
    6. the string address is pushed to the stack.

    Now, printf has no information about the number of arguments that has been sent to. Moreover, if -Wall is not issued in compilation, the compiler will not even complain about the inconsistent number of arguments. That is; the string may contain 3 %'s but the number of arguments in the printf line can be 1, 2, 3, 4, 5 or even can contain just the string itself without any arguments at all.

    Say, the string has 3 placeholders and you've send 5 arguments (printf("%d %f %s\n", k1, k2, k3, k4, k5)). If compilation warning is turned off, the compiler will not complain about excessive number of arguments (or insufficient number of placeholders). Knowing the stack address, printf will;

    1. treat the first integer width in the stack and print it as an integer (without knowing whether it is an integer or not),
    2. treat the next double width in the stack and print it as a double (without knowing whether it is a double or not),
    3. treat the next pointer width in the stack as a string address and will try to print the string at that address, until it finds a string terminator (provided, the address pointed to belong to that process; otherwise raises segmentation error).
    4. and ignore the remaining arguments.

提交回复
热议问题