I'm confused about in what order function arguments are evaluated when calling a C++ function. I have probably interepreted something wrong, so please explain if that is the case.
As an example, the legendary book "Programming Windows" by Charles Petzold contains code like this:
// hdc = handle to device context
// x, y = coordinates of where to output text
char szBuffer[64];
TextOut(hdc, x, y, szBuffer, snprintf(szBuffer, 64, "My text goes here"));
Now, the last argument is
snprintf(szBuffer, 64, "My text goes here")
which returns the number of characters written to the char[] szBuffer. It also writes the text "My text goes here" to the char[] szBuffer. The fourth argument is szBuffer, which contains the text to be written. However, we can see that szBuffer is filled in the fifth argument, telling us that somehow is the expression
// argument 5
snprintf(szBuffer, 64, "My text goes here")
evaluated before
// argument 4
szBuffer
Okay, fine. Is this always the case? Evaluation is always done from right to left? Looking at the default calling convention __cdecl:
The main characteristics of __cdecl calling convention are:
Arguments are passed from right to left, and placed on the stack.
Stack cleanup is performed by the caller.
Function name is decorated by prefixing it with an underscore character '_' .
(Source: Calling conventions demystified) (Source: MSDN on __cdecl)
It says "Arguments are passed from right to left, and placed on the stack". Does this mean that the rightmost/last argument in a function call is always evaluated first? Then the next to last etc? The same goes for the calling convention __stdcall, it also specified a right-to-left argument passing order.
At the same time, I came across posts like this:
How are arguments evaluated in a function call?
In that post the answers say (and they're quoting the standard) that the order is unspecified.
Finally, when Charles Petzold writes
TextOut(hdc, x, y, szBuffer, snprintf(szBuffer, 64, "My text goes here"));
maybe it doesn't matter? Because even if
szBuffer
is evaluated before
snprintf(szBuffer, 64, "My text goes here")
the function TextOut is called with a char* (pointing to the first character in szBuffer), and since all arguments are evaluated before the TextOut function proceeds it doesn't matter in this particular case which gets evaluated first.