casts and lvalues

C

CBFalconer

Keith said:
No, an argument is an expression whose value is *stored* in an object.
An argument and the corresponding parameter are two distinct things.

Please demonstrate such an accessible beast, accessed without first
storing it somewhere. The point is that the creation of the
argument value, and the storage of such for transmission to the
function, is inseparable.
 
K

Keith Thompson

CBFalconer said:
Please demonstrate such an accessible beast, accessed without first
storing it somewhere. The point is that the creation of the
argument value, and the storage of such for transmission to the
function, is inseparable.

No, they're not necessarily inseparable. It's entirely possible that
the evaluation of the argument (an expression) could be done in a
manner that's completely independent of the way it's eventually used,
namely being copied to the corresponding parameter.

For example, given
func(x + 42)
the generated code might look something like:

1: load value of x into accumulator
2: add constant 42 to accumulator
3: push contents of accumulator onto stack
4: call func

(I don't have any particular CPU in mind here.) Lines 1 and 2
evaluate the argument; line 3 copies the result to the parameter.
These actions are separate.

My real point is that the word "argument" and the word "parameter"
mean different things. They're both defined in section 3 of the
standard (either C90 or C99).

It's conceptually no different than an ordinary assignment or
initialization:

int obj = x + 42;

x + 42 is an expression; obj is an object. I think what you're saying
is the equivalent of claiming that the object and the initializer are
inseparable.
 
C

Chris Torek

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.]
 
B

Barry Schwarz

The result of the expression is stored in the stack.

There is an awful lot of generated code that leaves the value of an
evaluated expression in a register without ever placing it in any
memory, let alone a stack.
(Or its equivalent for the mythical machines without
stack)

I am extremely pleased that my mythical work on the mythical IBM
mainframe results in a very non-mythical paycheck.
The object exists, since we can even take its address
within the called function.

Obviously an intermittently true assertion.


Remove del for email
 
C

CBFalconer

Keith said:
.... snip ...

For example, given
func(x + 42)
the generated code might look something like:

1: load value of x into accumulator
2: add constant 42 to accumulator
3: push contents of accumulator onto stack
4: call func

(I don't have any particular CPU in mind here.) Lines 1 and 2
evaluate the argument; line 3 copies the result to the parameter.
These actions are separate.

Please show me how, on that machine, you avoid stages 3 and 4 by
writing a function call.
 
K

Keith Thompson

CBFalconer said:
Keith Thompson wrote:
... snip ...

Please show me how, on that machine, you avoid stages 3 and 4 by
writing a function call.

Please explain how that has anything to do with what we're talking
about.

Ok, maybe I misunderstood what you meant by "inseparable".

What I wrote upthread was:
| No, an argument is an expression whose value is *stored* in an object.
| An argument and the corresponding parameter are two distinct things.

You seemed to disagree with this.

Yes, the evaluation of the argument and the storing of the result in
the parameter always happen together; I suppose they're inseparable in
that sense. But they are two distinct things. An argument is an
expression (see C99 3.3); a parameter is an object (see C99 3.15).
Do you disagree with that?
 
R

Richard Tobin

1: load value of x into accumulator
2: add constant 42 to accumulator
3: push contents of accumulator onto stack
4: call func
[/QUOTE]
Please show me how, on that machine, you avoid stages 3 and 4 by
writing a function call.

Well, if you really want to... the evaluation of another argument
could occur between 2 and 3, and that evaluation could call exit() or
longjmp(), so that 1 and 2 would occur, but not 3 and 4. You can't
rely on this of course.

-- Richard
 
C

CBFalconer

Keith said:
Please explain how that has anything to do with what we're talking
about.

Ok, maybe I misunderstood what you meant by "inseparable".

What I wrote upthread was:
| No, an argument is an expression whose value is *stored* in an object.
| An argument and the corresponding parameter are two distinct things.

You seemed to disagree with this.

Yes, the evaluation of the argument and the storing of the result in
the parameter always happen together; I suppose they're inseparable
in that sense. But they are two distinct things. An argument is an
expression (see C99 3.3); a parameter is an object (see C99 3.15).
Do you disagree with that?

No, but this discussion is about casting destinations, which cannot
form a LHvalue.
 
K

Keith Thompson

CBFalconer said:
Keith Thompson wrote: [...]
What I wrote upthread was:
| No, an argument is an expression whose value is *stored* in an object.
| An argument and the corresponding parameter are two distinct things.

You seemed to disagree with this.

Yes, the evaluation of the argument and the storing of the result in
the parameter always happen together; I suppose they're inseparable
in that sense. But they are two distinct things. An argument is an
expression (see C99 3.3); a parameter is an object (see C99 3.15).
Do you disagree with that?

No, but this discussion is about casting destinations, which cannot
form a LHvalue.

This discussion has drifted considerably. It started out as a
discussion of a proposed extension to allow casts to be treated as
lvalues (presumably if an only if the operand is an lvalue), but this
subthread is about whether a particular expression, a function call,
contains any lvalues.

Do you agree with what I wrote above?
No, an argument is an expression whose value is *stored* in an object.
An argument and the corresponding parameter are two distinct things.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Casts on lvalues 74
Casts 81
Union and pointer casts? 13
casts and pointers 0
Pointer casts for OOP 2
sub-int types, casts, MISRA and RH's writings 6
Question about casts 7
Pointer to Structure Casts 5

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top