A way to do this without invoking undefined behavior would be to simply print a message as each argument is evaluated:
#include <stdio.h>
static void foo(int a, int b, int c) {}
static int argument(int n)
{
printf("Argument %d.\n", n);
return n;
}
int main(void)
{
foo(argument(0), argument(1), argument(2));
return 0;
}
However, that will only show you the order of argument evaluation in one specific execution of the program. The order of argument evaluation is not specified by the C standard and may change for a variety of reasons. For example, if you pass a function simple arguments, the compiler might evaluate them last-to-first so that it can easily put them on the stack in the order required for calling subroutines on that platform. But suppose, with the same compiler version and compilation switches, you pass a function some complex arguments, some of which have common subexpressions. The compiler might decide to evaluate those arguments first, to take advantage of the common subexpressions.
The compiler can even evaluate part of one argument, then part of another, then part of the first, then a third argument, then evaluate an expression preceding the function call (provided sequence point behavior is preserved), then finish the second argument.
The order of argument evaluation is not something you can rely on.