Objects are not lvalues. Lvalues are not objects.
Well, they *should* be, except that the Standard gets this wrong.
(Of course, the Standard is right by definition. It's just that
the C89 definition of "lvalue" is a little flawed, and the C99
definition -- which attempt to fix the problem -- makes things even
worse. Hence my not-entirely-serious claim above. An lvalue
*should* be an "expression that designates an object", as in C89,
with the "designates" being interpreted loosely enough so that *f()
is a "compile time lvalue" even if f() potentially returns NULL,
and simply produces undefined run-time behavior if f() actually
does return NULL.)
Arguments are not parameters. Parameters are not arguments.
Parameters are objects. Arguments are expressions, not objects.
Indeed.
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;
}
Actually, I think we get a better example when we look at
"narrow" arguments, and take a concrete implementation such
as the SPARC or MIPS -- one that uses registers for parameters,
on a machine that has no "narrow" registers. Hence:
void func(char param) /* or: void func(param) char param; */
{
... otherwise the same as above ...
}
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.
And if we use that concrete-machine example, we find that the actual
argument -- 42 -- is shoved into register %o0 (on SPARC; different
name on MIPS) at before the call, but is *not* a "char" at this
point. Registers hold full 32 (or 64) bit values. Only after
func() actually starts up is the 32 bit value stored in a narrow,
8-bit object in memory. Hence the *argument* exists *before* the
function begins executing, but the *parameter* exists only *after*
that point (after the "save" instruction, which is extremely-roughly
similar to the x86 "enter" instruction).
So the question we seem to be discussing is this: is there an lvalue
on line 8? The answer is clearly no. [ discussion snipped ]
Indeed.
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.
I think that we have to assume, in principle at least and in practice
on real machines like the SPARC and MIPS, the parameter is "created"
after entry to the function. Optimization often shuffles things
around so that the "creation" winds up using no instructions after
all[%], but this is merely a matter of cleverness-of-implementation.
[% Provided, of course, that the parameter does not require narrowing.
If it does require narrowing, sometimes it can be done "in-register"
with a masking instruction, but that again makes it obvious that
the "parameter creation" happens after the function is called, not
before.]