Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of evaluation of arguments in function calling?

I am studying about undefined behavior in C and I came to a statement that states that

there is no particular order of evaluation of function arguments

but then what about the standard calling conventions like _cdecl and _stdcall, whose definition said (in a book) that arguments are evaluated from right to left.

Now I am confused with these two definitions one, in accordance of UB, states different than the other which is in accordance of the definition of calling convention. Please justify the two.

like image 835
OldSchool Avatar asked Mar 24 '14 17:03

OldSchool


People also ask

What is the order of arguments when calling a function?

3. Positional Arguments. During a function call, values passed through arguments should be in the order of parameters in the function definition. This is called positional arguments.

What is the order of evaluation?

Order of evaluation refers to the operator precedence and associativity rules according to which mathematical expressions are evaluated.

Does the order of arguments in a function matter?

Argument Order MattersThe order or arguments supplied to a function matters. R has three ways that arguments supplied by you are matched to the formal arguments of the function definition: By complete name: i.e. you type main = "" and R matches main to the argument called main .

What is the order of evaluation in C language?

Only the sequential-evaluation ( , ), logical-AND ( && ), logical-OR ( || ), conditional-expression ( ? : ), and function-call operators constitute sequence points, and therefore guarantee a particular order of evaluation for their operands.


2 Answers

Argument evaluation and argument passing are related but different problems.

Arguments tend to be passed left to right, often with some arguments passed in registers rather than on the stack. This is what is specified by the ABI and _cdecl and _stdcall.

The order of evaluation of arguments before placing them in the locations that the function call requires is unspecified. It can evaluate them left to right, right to left, or some other order. This is compiler dependent and may even vary depending on optimization level.

like image 139
Graznarak Avatar answered Oct 06 '22 00:10

Graznarak


_cdecl and _stdcall merely specify that the arguments are pushed onto the stack in right-to-left order, not that they are evaluated in that order. Think about what would happen if calling conventions like _cdecl, _stdcall, and pascal changed the order that the arguments were evaluated.

If evaluation order were modified by calling convention, you would have to know the calling convention of the function you're calling in order to understand how your own code would behave. That's a leaky abstraction if I've ever seen one. Somewhere, buried in a header file someone else wrote, would be a cryptic key to understanding just that one line of code; but you've got a few hundred thousand lines, and the behavior changes for each one? That would be insanity.

I feel like much of the undefined behavior in C89 arose from the fact that the standard was written after multiple conflicting implementations existed. They were maybe more concerned with agreeing on a sane baseline that most implementers could accept than they were with defining all behavior. I like to think that all undefined behavior in C is just a place where a group of smart and passionate people agreed to disagree, but I wasn't there.

I'm tempted now to fork a C compiler and make it evaluate function arguments as if they're a binary tree that I'm running a breadth-first traversal of. You can never have too much fun with undefined behavior!

like image 37
Peter G Avatar answered Oct 05 '22 23:10

Peter G