jacob navia said:
If within the called function the address of that parameter is taken
it must be stored in the stack.
Obviously the compiler can optimize it away, etc.
But if it lives in a register, it still is somewhere there.
In the same vein, if you say:
int c;
c = 56;
The fact that the integer "c" is stored in a register doesn't mean that
it is not a lvalue isn't it?
The object c is an object, not an lvalue.
The expression c on the left hand side of the assignment clearly is an
lvalue.
We have to separate conceptually stores that can be optimized away, and
details of compiler decisions that store the integer in a register or
whatever.
If I declare
int f;
f = 56;
There is an "f" object even if the compiler realizes that f is not used
anywhere in the function and optimizes the whole stuff away!
Of course f is an object.
Objects are not lvalues. Lvalues are not objects.
Arguments are not parameters. Parameters are not arguments.
Parameters are objects. Arguments are expressions, not objects.
What exactly are we arguing about here?
Let's take a simple example:
#include <stdio.h>
void func(int param)
{
printf("param = %d\n", param);
}
int main(void)
{
func(42); /* line 8 */
return 0;
}
In the following, I'll use quotation marks to delimit chunks of code.
The expression "42" on line 8 is an *argument* (not a parameter).
That expression is evaluated, and the result is assigned to "param",
which is a *parameter* (not an argument). The parameter "param",
which is an object, is created as part of the function call. The
result of evaluating the argument (an expression) is assigned to the
parameter (an object).
An argument and a parameter are two very different things. The
argument doesn't become, and is not converted to, the parameter; the
argument's value is assigned to the parameter.
I believe there's some ambiguity in the standard about just when the
parameter object is created. One passage implies it's created during
the execution of line 8, before "func" is actually called; another
implies that it's created during the execution of "func" itself, just
after execution passes the opening "{". But that ambiguity is not
really such a big deal; since nothing can access that object during
the window of ambiguity.
So the question we seem to be discussing is this: is there an lvalue
on line 8? The answer is clearly no.
What is an lvalue? Ignoring the way both the C90 and C99 standards
have screwed up the definition of the term, an lvalue is an expression
that designates an object. There are several expressions on line 8,
but none of them designate objects.
"42" clearly does not designate an object, so it's not an lvalue.
(The fact that the result of that subexpression is assigned to an
object doesn't make it an lvalue, any more than "43" in "x = 43;" is
an lvalue.)
"func" is a function designator, not an lvalue.
"func(42)" also does not designate an object; it merely yields a
value.
There is a separate question here: is an object created on line 8?
The answer is, I believe, ambiguous. If we assume that the parameter
object is created prior to the function call, then yes, an object is
created on line 8 (but, going back to the previous question, there is
no lvalue on line 8 that refers to that object).
Now if we want to discuss when parameters are created, that's great --
but that discussion doesn't need to consider lvalues.