Home > front end >  order of evaluation of varadic arguments?
order of evaluation of varadic arguments?

Time:10-05

I understand that for an ordinary C functions:

g1(f1(), f2() f3())

that the order of evaluating the arguments is unspecified: f3() might be called before f1() or vice versa.

But does the same hold true for varadic functions? The definition of va_arg() says:

Each invocation of the va_arg macro modifies ap to point to the next variable argument.

Though it doesn't specify what it means by 'next' (left to right or right to left?), common use cases make it seem likely that it means left to right.

Furthermore, can one assume that the required first argument is evaluated before (or after) the variable arguments? Or is that also unspecified?

  void g2(int a, ...);

I suppose a strict reading of this says that one cannot assume any particular order of evaluation. But it certainly would make writing functions like printf() much more difficult, if not intractable.

CodePudding user response:

The order of evaluation of function arguments does not (strictly) depend on whether the function in question is variadic or not. In both cases, the order is unspecified.

The description of va_arg is just telling you what order it reads the arguments in. By the time you're inside the variadic function, the arguments were already evaluated and passed to the function.

CodePudding user response:

I understand that for an ordinary C functions [...] the order of evaluating the arguments is unspecified [...] But does the same hold true for varadic functions? The definition of va_arg() says [...]

C specifies that

There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call

(C17 6.5.2.2/7)

That applies to all functions, including variadic ones. Among other things, it means that the specifications for the va_arg macro are irrelevant to the order of evaluation of the actual arguments to the function in which that macro appears. All actual arguments to the function are evaluated before execution of the function body begins.

The only distinction C draws on the calling side between variadic functions and non-variadic functions is in the argument type conversions that apply. The variable arguments to a variadic function (or to a function without an in-scope prototype) are subject to the default argument promotions, whereas that is not the case for non-variadic arguments to functions with in-scope prototypes.

Furthermore, can one assume that the required first argument is evaluated before (or after) the variable arguments? Or is that also unspecified?

It is also unspecified. Again, the only distinction C makes between the semantics of calling a variadic function and of calling a non-variadic one is to do with rules for argument type promotions. And that's not really so much a distinction as it is covering cases that don't otherwise arise, and even then it is in a manner that is consistent with other C semantics for arguments whose types are not specified via a function prototype.

I suppose a strict reading of this says that one cannot assume any particular order of evaluation. But it certainly would make writing functions like printf() much more difficult, if not intractable.

No "strict" reading is required. C does not specify any rules for the relative order of evaluation of arguments to the same function call. Period. But that causes no particular issue with the implementation of variadic functions, because all the arguments are evaluated before execution of the function body starts. Variadic functions are subject to constraints on the order in which the values of the variable arguments are read within the function, but that has nothing to do with the order in which the argument expressions are evaluated on the caller's side.

CodePudding user response:

Each invocation of the va_arg macro modifies ap to point to the next variable argument.

This refers to "left to right", with the arguments passed to ....

Furthermore, can one assume that the required first argument is evaluated before (or after) the variable arguments?

This is also unspecified. There is no exception for variadic arguments when it comes to order of evaluation, AFAIK.

The arguments are all evaluated when you call the function, although the order is not specificed. By the time you use the va_arg macro, you have already evaluated all the arguments.

It's the same way if I call f(int a, int b), both a and b have already been evaluated by the time I'm in the body of f.

  • Related