Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > casts and lvalues

Reply
Thread Tools

casts and lvalues

 
 
Richard Bos
Guest
Posts: n/a
 
      06-26-2007
Mark McIntyre <(E-Mail Removed)> wrote:

> On Mon, 25 Jun 2007 00:25:32 +0200, in comp.lang.c , jacob navia
> <(E-Mail Removed)> wrote:
>
> >if I would add support for it, are there any TECHNICAL drawbacks?

>
> I guess the point is, nobody commenting here can currently see any
> actual purpose for adding it. Before asking if there are any technical
> drawbacks, one needs to first ascertain a use.
>
> Imagine you're a car designer. Do you ask "is there a technical
> drawback with adding a beach umbrella on the steering wheel?" or do
> first you ask why....


jacob might want to ponder this quotation from a superior specimen among
his compatriots:

La perfection est atteinte non quand il ne reste rien ajouter,
mais quand il ne reste rien enlever.

Richard
 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      06-26-2007
Richard Heathfield wrote:
> CBFalconer said:
>> Richard Heathfield wrote:
>>> CBFalconer said:
>>>> Richard Heathfield wrote:

> <snip>
>>>>> For example, there is
>>>>> no lvalue in the (pointless but legal) statement:
>>>>>
>>>>> toupper((unsigned char)c);
>>>> Yes there is, although it is well hidden. The functional parameter.
>>> No, it isn't well hidden. It isn't *there*. Not in that statement.

>> We must be missing each others points. Where do you think the
>> conversion of c goes?

>
> It could easily go into a register, but that's beside the point. There's
> no object in the statement I presented.


The result of the expression is stored in the stack.
(Or its equivalent for the mythical machines without
stack)

The object exists, since we can even take its address
within the called function.



 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      06-26-2007
Stephen Sprunk wrote:
> "Joe Wright" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> Well, an lvalue expression tells us where the object is so that we
>> might store a value there. The current value stored in the object may
>> be of no interest at all. Let's imagine we have two 4-byte int objects
>> in memory at address 200.

> ...
>> In C, a cast is an explicit conversion of a value from one type to
>> another. The result is a value of the destination type. What would we
>> expect of..
>>
>> (short)a = b:
>>
>> ..whether gcc 'allows' it or not? C89 apparently does not allow it.

>
> Logically, it would be equivalent to (i.e. shorthand for) the expression:
>
> *(short *)&a = b;
>
> However, doing that is generally a bad idea for several different
> reasons, and I am philosophically opposed to making bad ideas easier to
> express. They should stand out in code, not be made invisible.
>
> There's also the argument that most of the features added in C99 were
> extensions that were widely implemented and oconsidered to add value;
> given that the GCC folks initially implemented but then deprecated this
> feature, and GCC is one of the most widely used compilers, that doesn't
> bode well for this being added to the next revision of C. It also
> doesn't appear to add any value, since you can already accomplish the
> same bad idea today if you really want to.
>
> S
>



Thanks for your answer.

lcc-win32 does NOT support this gcc extension, but when speaking about
casts in my tutorial I wanted to EXPLAIN why it is a bad idea...
Users will discover this eventually, and an explanation is necessary.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-26-2007
jacob navia <(E-Mail Removed)> writes:
> Richard Heathfield wrote:
>> CBFalconer said:
>>> Richard Heathfield wrote:
>>>> CBFalconer said:
>>>>> Richard Heathfield wrote:

>> <snip>
>>>>>> For example, there is
>>>>>> no lvalue in the (pointless but legal) statement:
>>>>>>
>>>>>> toupper((unsigned char)c);
>>>>> Yes there is, although it is well hidden. The functional parameter.
>>>> No, it isn't well hidden. It isn't *there*. Not in that statement.
>>> We must be missing each others points. Where do you think the
>>> conversion of c goes?

>> It could easily go into a register, but that's beside the
>> point. There's no object in the statement I presented.

>
> The result of the expression is stored in the stack.
> (Or its equivalent for the mythical machines without
> stack)


Mythical? Real-world examples of such machines have been discussed in
this newsgroup.

> The object exists, since we can even take its address
> within the called function.


Yes, *within* the called function. The object (the parameter) doesn't
exist outside the function; it's a local object with automatic storage
duration.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      06-26-2007
Keith Thompson wrote:
> jacob navia <(E-Mail Removed)> writes:
>> Richard Heathfield wrote:
>>> CBFalconer said:
>>>> Richard Heathfield wrote:
>>>>> CBFalconer said:
>>>>>> Richard Heathfield wrote:
>>> <snip>
>>>>>>> For example, there is
>>>>>>> no lvalue in the (pointless but legal) statement:
>>>>>>>
>>>>>>> toupper((unsigned char)c);
>>>>>> Yes there is, although it is well hidden. The functional parameter.
>>>>> No, it isn't well hidden. It isn't *there*. Not in that statement.
>>>> We must be missing each others points. Where do you think the
>>>> conversion of c goes?
>>> It could easily go into a register, but that's beside the
>>> point. There's no object in the statement I presented.

>> The result of the expression is stored in the stack.
>> (Or its equivalent for the mythical machines without
>> stack)

>
> Mythical? Real-world examples of such machines have been discussed in
> this newsgroup.
>
>> The object exists, since we can even take its address
>> within the called function.

>
> Yes, *within* the called function. The object (the parameter) doesn't
> exist outside the function; it's a local object with automatic storage
> duration.
>


Thanks. You agree with me then, that the object exists, and exists
before the call, even if it is not accessible.

This is obvious if we read the standard 6.5.2.2 "Function calls", where
it is specified that after all assignments are done to the function
arguments there is a sequence point. At that sequence point the
arguments have been assigned but they are still not accessible since the
function call is not done yet.

Obviously the objects exist within the function call. They have a
constant address, and they retain their last assigned value.
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      06-26-2007
In article <468057e3$0$16267$(E-Mail Removed)>,
Stephen Sprunk <(E-Mail Removed)> wrote:

>> (short)a = b:


>Logically, it would be equivalent to (i.e. shorthand for) the expression:
>
>*(short *)&a = b;


That is not the interpretation of it in gcc, as explained somewhere else
in the thread.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      06-26-2007
jacob navia said:

> Richard Heathfield wrote:
>> CBFalconer said:
>>> Richard Heathfield wrote:
>>>> CBFalconer said:
>>>>> Richard Heathfield wrote:

>> <snip>
>>>>>> For example, there is
>>>>>> no lvalue in the (pointless but legal) statement:
>>>>>>
>>>>>> toupper((unsigned char)c);
>>>>> Yes there is, although it is well hidden. The functional
>>>>> parameter.
>>>> No, it isn't well hidden. It isn't *there*. Not in that statement.
>>> We must be missing each others points. Where do you think the
>>> conversion of c goes?

>>
>> It could easily go into a register, but that's beside the point.
>> There's no object in the statement I presented.


(I misspoke. The c object is clearly an object!)

> The result of the expression is stored in the stack.
> (Or its equivalent for the mythical machines without
> stack)


Or a register, or in some part of memory, or on disk, or on tape, or on
a piece of paper. The C Standard imposes no requirement on
implementations to store the results of expressions on a stack, not
even for implementations that use stacks.

> The object exists, since we can even take its address
> within the called function.


The implementation *may* create an object *as a result of* the toupper
call, but the result of the expression (unsigned char)c is not an
lvalue just because the implementation does exercise its licence to
create an object to store it during the execution of toupper.

If that /were/ true, then the result of the expression (unsigned
char)(6+42) would also be an lvalue.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-26-2007
jacob navia <(E-Mail Removed)> writes:
[...]
> lcc-win32 does NOT support this gcc extension, but when speaking about
> casts in my tutorial I wanted to EXPLAIN why it is a bad idea...
> Users will discover this eventually, and an explanation is necessary.


(The extension being discussed is allowing casts as lvalues.)

You're writing a tutorial about C, right? C doesn't allow casts as
lvalues. Why even mention it?

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      06-26-2007
jacob navia said:

> Keith Thompson wrote:
>> jacob navia <(E-Mail Removed)> writes:


<snip>

>>> The object exists, since we can even take its address
>>> within the called function.

>>
>> Yes, *within* the called function. The object (the parameter)
>> doesn't exist outside the function; it's a local object with
>> automatic storage duration.
>>

>
> Thanks. You agree with me then, that the object exists, and exists
> before the call, even if it is not accessible.


No, he doesn't, and neither do I. As he rightly said, the object doesn't
exist until the function is called (if indeed a function *is* called
for the expression under consideration, which is not necessarily the
case). It's a local object with automatic storage duration, so it
doesn't exist until the function call actually happens.

> This is obvious if we read the standard 6.5.2.2 "Function calls",
> where it is specified that after all assignments are done to the
> function arguments there is a sequence point. At that sequence point
> the arguments have been assigned but they are still not accessible
> since the function call is not done yet.


Two problems with this - firstly, you're trying to nudge the discussion
further and further into the called function in an attempt to shore up
your case, but we're discussing the cast-expression, not the execution
details of the called function; and secondly, there isn't necessarily a
function call at all! The expression, remember, was toupper((unsigned
char)c), and the implementation is perfectly at liberty to convert this
into something like:
(((unsigned char)c) == EOF) ? EOF : __toupper[((unsigned char)c)]

where __toupper is an array in read-only memory.

*Now* where is your lvalue?

> Obviously the objects exist within the function call. They have a
> constant address, and they retain their last assigned value.


Until the function (if there /is/ a function) returns, yes.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-26-2007
jacob navia <(E-Mail Removed)> writes:
> Keith Thompson wrote:
>> jacob navia <(E-Mail Removed)> writes:

[...]
>>> The object exists, since we can even take its address
>>> within the called function.

>> Yes, *within* the called function. The object (the parameter)
>> doesn't exist outside the function; it's a local object with
>> automatic storage duration.

>
> Thanks. You agree with me then, that the object exists, and exists
> before the call, even if it is not accessible.


I didn't say that, but I agree, more or less.

> This is obvious if we read the standard 6.5.2.2 "Function calls",
> where it is specified that after all assignments are done to the
> function arguments there is a sequence point. At that sequence point
> the arguments have been assigned but they are still not accessible
> since the function call is not done yet.
>
> Obviously the objects exist within the function call. They have a
> constant address, and they retain their last assigned value.


An *argument* is not an object. An argument is an expression
appearing between the parentheses in a function call; see C99 3.3.
A *parameter* is an object; see C99 3.15. Please keep the
terminology straight.

The standard is a bit vague, and perhaps even contradictory, about
the lifetime of a parameter. See C99 6.5.2.2p4:

An argument may be an expression of any object type. In preparing
for the call to a function, the arguments are evaluated, and each
parameter is assigned the value of the corresponding argument.

implying that a parameter is created before the function is called.
But C99 6.9.1p9 says:

Each parameter has automatic storage duration. Its identifier is
an lvalue, which is in effect declared at the head of the compound
statement that constitutes the function body (and therefore cannot
be redeclared in the function body except in an enclosed block).

which implies that the parameter object isn't created until control
passes the opening '{' of the function.

I'm not suggesting that this is a real problem in the standard, just
that it's difficult to say whether a parameter object exists before
the function is called.

But in any case, the question from upthread is whether this statement:

toupper((unsigned char)c);

contains an lvalue. c is an lvalue, but (unsigned char)c is not, and
statement does *not* contain an lvalue that refers to the parameter.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Casts on lvalues BartC C Programming 74 12-17-2012 09:37 PM
lvalues and rvalues Nicklas Karlsson C Programming 127 05-05-2010 10:58 PM
Lvalues and Rvalues ramasubramanian.rahul@gmail.com C Programming 3 10-14-2006 09:55 PM
Avoiding "use of cast expressions in lvalues is deprecated" steve.j.donovan@gmail.com C Programming 23 09-21-2006 05:45 PM
lvalues -> incomplete types Mantorok Redgormor C Programming 7 02-07-2004 03:45 PM



Advertisments