473,386 Members | 1,610 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

casts and lvalues

Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
int main(void)
{
long long a;
char *n;

(char *)a = n;
}
This will fail under lcc-win32, but MSVC and gcc will
accept it. I know that the standard prescribes the behavior
that lcc-win32 uses, but I left that behavior after a big
discussion about this several years ago. I had modified it,
and some people raised hell.

What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?

Apparently gcc and msvc are still used, and this doesn't seem
to produce any big problems.

Thanks in advance for your comments, and I thank all people
that participated in the discussion yesterday.

jacob
Jun 24 '07 #1
61 2738
jacob navia said:
Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues
It isn't a matter of opinion. They're not legal C. A cast yields a
value, but not an lvalue.

<snip>
What are the problems of doing this?
It doesn't compile.
I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
Implementors jumped at C89 like a pack of starving stoats on a squirrel.
But they have stayed away from C99 in droves. I don't see them suddenly
all agreeing to support a particular extension, all with the same
syntax and semantics. So the fundamental problem would be that your
proposal wouldn't be accepted.

--
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
Jun 24 '07 #2
jacob navia wrote:
Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
[...]
What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
int a = 1;
void f(double *d) {
if (a == 1) *d = 2;
if (a == 2) *d = 0;
}
int main(void) {
f(&(double) a);
return a;
}

What would this program return?
Jun 24 '07 #3
Harald van Dijk wrote:
jacob navia wrote:
>Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
[...]
What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?

int a = 1;
void f(double *d) {
if (a == 1) *d = 2;
if (a == 2) *d = 0;
}
int main(void) {
f(&(double) a);
return a;
}

What would this program return?
It doesn't compile here. You seem to want to pretend a is a double.

f((double*)&a);

will at least compile.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jun 24 '07 #4
Richard Heathfield wrote:
jacob navia said:
>Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues

It isn't a matter of opinion. They're not legal C. A cast yields a
value, but not an lvalue.

<snip>
>What are the problems of doing this?

It doesn't compile.
>I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?

Implementors jumped at C89 like a pack of starving stoats on a squirrel.
But they have stayed away from C99 in droves. I don't see them suddenly
all agreeing to support a particular extension, all with the same
syntax and semantics. So the fundamental problem would be that your
proposal wouldn't be accepted.
But this is just politics. I do not want to do any proposal nor do
I want to modify anything. I just want to know what TECHNICAL problems
could arise if that extension (that is provided at least by the
compilers I mentioned) would be part of the language.

Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.
Jun 24 '07 #5
In article <46**********************@news.orange.fr>,
>int main(void)
{
long long a;
char *n;

(char *)a = n;
}
>This will fail under lcc-win32, but MSVC and gcc will
accept it.
Gcc has, I think, always warned about this if you give enough flags,
and seems to reject it by default in recent versions.
>What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
So long as you can specifiy exactly what it means, there would be no
problem adding it to the language. Of course, once you've specified
exactly what it means it's easy enough to manage without it.

I've always thought its use in implementing a "program counter"
variable was reasonable, where a generic pointer is cast to various
types and incremented by the same amount, e.g.

op = *((operator *)pc)++;
switch(op)
{
...
case ADD:
arg1 = *((int *)pc)++;
arg2 = *((int *)pc)++;
whatever = arg1 + arg2;
...

But those writing this style of code can easily enough work around it.
>Apparently gcc and msvc are still used, and this doesn't seem
to produce any big problems.
Apparently gcc's implementors see sufficient problems to not accept it
by default, but those problems may just be compatibility ones.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jun 24 '07 #6
On Sun, 24 Jun 2007 23:20:03 +0200, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.frwrote:

(of
long long a;
char *n;

(char *)a = n;
)
>Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.
Because its meaningless in my view. What exactly does the above do?

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 24 '07 #7
jacob navia <ja***@jacob.remcomp.frwrites:
Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
>int main(void)
{
long long a;
char *n;
(char *)a = n;
}

This will fail under lcc-win32, but MSVC and gcc will
accept it. I know that the standard prescribes the behavior
that lcc-win32 uses, but I left that behavior after a big
discussion about this several years ago. I had modified it,
and some people raised hell.

What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
[...]

This extension doesn't seem to me to be particularly useful. The
above would be more clearly written as:

long long a;
char *n;
a = (long long)n;

Another problem with this, as with any extension, is that it
encourages programmers to write non-portable code that depends on it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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"
Jun 24 '07 #8
Mark McIntyre wrote:
On Sun, 24 Jun 2007 23:20:03 +0200, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.frwrote:

(of
long long a;
char *n;

(char *)a = n;
)
>Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.

Because its meaningless in my view. What exactly does the above do?
Moves the contents of n (an address) into the memory locations of a,
that can hold a pointer is sizeof(void *) <= sizeof(long long);

I am not saying that this is nice/the best thing since sliced bread
but that is what it does.

Jun 24 '07 #9
Keith Thompson wrote:
jacob navia <ja***@jacob.remcomp.frwrites:
>Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
>>int main(void)
{
long long a;
char *n;
(char *)a = n;
}
This will fail under lcc-win32, but MSVC and gcc will
accept it. I know that the standard prescribes the behavior
that lcc-win32 uses, but I left that behavior after a big
discussion about this several years ago. I had modified it,
and some people raised hell.

What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
[...]

This extension doesn't seem to me to be particularly useful. The
above would be more clearly written as:

long long a;
char *n;
a = (long long)n;
Granted.

It is clearer but the question is not if this is pleasing but if there
would be any problems (in the sense of contradictions or buggy language
specifications) if casts could be lvalues.
Another problem with this, as with any extension, is that it
encourages programmers to write non-portable code that depends on it.
Yes, of course. lcc-win32 doesn't even support this extension. But
if I would add support for it, are there any TECHNICAL drawbacks?
I mean, if somebody asks me to support overloading addition
with

int operator+(struct FOO *a,int b);

I would say NO that can't be done because addition of a pointer and
an integer is already used in the language to access the nth element
using a pointer as base, i.e.
struct FOO *p;
p + 6
addresses the sixth element after the element pointed by p. If I would
implement such an extension I would introduce an ambiguity in the
language.

Is that the case with casts as lvalues?

Jun 24 '07 #10
In article <ft********************************@4ax.com>,
Mark McIntyre <ma**********@spamcop.netwrote:
long long a;
char *n;

(char *)a = n;
>>Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.
>Because its meaningless in my view.
C constructs are no natural phenomena. They are meaningful if people
assign meaning to them. And several compilers *have* assigned meaning
to casts as lvalues,
>What exactly does the above do?
I believe that it's intended to be equivalent to "a = (long long)n'.
As such, it's not very useful. Some more complicated uses are more
obviously useful, as I've noted elsewhere.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jun 24 '07 #11
jacob navia <ja***@jacob.remcomp.frwrites:
Richard Heathfield wrote:
>jacob navia said:
>>Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues
It isn't a matter of opinion. They're not legal C. A cast yields a
value, but not an lvalue.
<snip>
>>What are the problems of doing this?
It doesn't compile.
>>I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
Implementors jumped at C89 like a pack of starving stoats on a
squirrel. But they have stayed away from C99 in droves. I don't see
them suddenly all agreeing to support a particular extension, all
with the same syntax and semantics. So the fundamental problem would
be that your proposal wouldn't be accepted.

But this is just politics. I do not want to do any proposal nor do
I want to modify anything. I just want to know what TECHNICAL problems
could arise if that extension (that is provided at least by the
compilers I mentioned) would be part of the language.

Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.
Why *should* casts be lvalues?

For any proposed addition to the language, the burden is on its
advocates to demonstrate that its advantages outweigh the costs of
updating the standard *and* of updating every implementation to
support it.

The main technical problem, in my opinion, is the difficulty of
defining the semantics in all possible cases, something that must be
done if this is to become a language feature. I see no particular
advantage that outweighs this difficulty; I know of no use of
cast-as-lvalue that can't be written equivalently in legal C.

A cast specifies a conversion of a given value (the result of
evaluating an expression) to a specified type. That's relatively
simple to describe and to understand. Allowing casts as lvalues would
require a much more complex model of what casts mean.

I presume you're proposing that a cast would be an lvalue only if the
operand is itself an lvalue. That's just one of the many details that
must be specified before any such proposal can be taken seriously.

Even if such a feature were added to a future version of the standard,
there's a real risk that some obscure corner case could be neglected,
leading to a flaw in the standard. In two attempts a decade apart,
the commitee hasn't even managed to come up with a coherent definition
of the word "lvalue".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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"
Jun 24 '07 #12
[from article <46**********************@news.orange.fr>: gcc accepts:]
>>int main(void)
{
long long a;
char *n;

(char *)a = n;
}
In article <f5***********@pc-news.cogsci.ed.ac.uk>
Richard Tobin <ri*****@cogsci.ed.ac.ukwrote:
>Gcc has, I think, always warned about this if you give enough flags,
Indeed.
>and seems to reject it by default in recent versions.
Yes. This illustrates one of the dangers of relying on compiler
extensions: the compiler-writer may eventually realize the folly
of that particular extension, and remove it. (The extension, not
the folly. :-) )

GCC's old definition of (cast)obj = expr was:

((cast)(obj = (T)(expr)))

where T is the type of the object "obj", -- so the code above, with
"a" being "long long", really "meant":

(char *)(a = (long long)n);

Many programmers seemed to have expected it to mean:

*(char *)&a = n;

which, on a typical 32-bit-pointer, 64-bit-"long long" machine,
sets just half of the object "a", leaving the other half unmodified.
GCC's old interpretation sets all 64 bits. The overly-clever
programmer, believing it set only 32 bits, set the other 32 bits
to something useful first, and then was surprised when those bits
were clobbered.

(If you use Standard C to write "what you mean", you will not be
surprised by whatever bizarre interpretation some compiler-writer
uses for his or her particular extension.)
>I've always thought its use in implementing a "program counter"
variable was reasonable, where a generic pointer is cast to various
types and incremented by the same amount, e.g.

op = *((operator *)pc)++;
switch(op)
{
...
case ADD:
arg1 = *((int *)pc)++;
arg2 = *((int *)pc)++;
whatever = arg1 + arg2;
...

But those writing this style of code can easily enough work around it.
Yes -- and, assuming "void *pc" for the above and that "operator" is
a typedef-name for a type smaller than plain "int", the above tends
to malfunction on various machines. So it might not be the best
way to write the code, even with the more verbose workaround:

op = *(operator *)pc, pc = (unsigned char *)pc + sizeof(operator);
switch (op)
{
...
case ADD:
arg1 = *(int *)pc, pc = (unsigned char *)pc + sizeof(int);
arg2 = *(int *)pc, pc = (unsigned char *)pc + sizeof(int);
whatever = arg1 + arg2;

where the comma-expression versions above might be hidden behind
a macro and then modified a bit:

#define FETCH(ty, pc) \
(pc = (unsigned char *)(pc) + sizeof(ty), ((ty *)pc)[-1])

Note: giving "pc" type "unsigned char *" simplifies this even
further:

#define FETCH(ty, pc) (((ty *)(pc += sizeof(ty)))[-1])

switch (FETCH(operator, pc)) {
...
case ADD:
arg1 = FETCH(int, pc);
whatever = arg1 + FETCH(int, pc);
...

The alignment trap remains, however: for this to work in general,
the pointer must remain aligned for each type "ty". The simplest
way to guarantee such alignment is to use just a single type, in
this case, "int". If "pc" is always going to refer to "int"s, we
can remove the FETCH macro's "ty" argument, change "pc" to "int
*", and simply use *pc++ -- and thus remove all need for the FETCH
macro itself.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jun 24 '07 #13
On Jun 25, 8:54 am, Joe Wright <joewwri...@comcast.netwrote:
Harald van Dijk wrote:
jacob navia wrote:
Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
[...]
What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
int a = 1;
void f(double *d) {
if (a == 1) *d = 2;
if (a == 2) *d = 0;
}
int main(void) {
f(&(double) a);
return a;
}
What would this program return?

It doesn't compile here. You seem to want to pretend a is a double.
Did you read the text you quoted? The point of
this thread is to ask what problems would occur
if the above code were made legal.

Jun 24 '07 #14
jacob navia wrote:
>
Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
I don't like it because the semantics are srewed up.
An lvalue converted to a different type,
refers to memory that was never reserved.

--
pete
Jun 24 '07 #15
jacob navia wrote:
>
.... snip ...
>
Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.
A cast requires a destination (i.e. a lvalue) to receive the
converted object. Without a destination, such does not exist.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 25 '07 #16
jacob navia wrote:
>
Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
>int main(void) {
long long a;
char *n;

(char *)a = n;
}

This will fail under lcc-win32, but MSVC and gcc will
accept it. I know that the standard prescribes the behavior
that lcc-win32 uses, but I left that behavior after a big
discussion about this several years ago. I had modified it,
and some people raised hell.
Don't know about MSVC, but gcc (later versions) will also reject
this. A cast cannot be a lvalue. Also you have the types
confused.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 25 '07 #17
CBFalconer said:
jacob navia wrote:
>>
... snip ...
>>
Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.

A cast requires a destination (i.e. a lvalue) to receive the
converted object.
No, it doesn't. No object is converted by a cast, and casts do not
*require* lvalues to receive their results. For example, there is no
lvalue in the (pointless but legal) statement:

toupper((unsigned char)c);

--
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
Jun 25 '07 #18
On Sun, 24 Jun 2007 21:13:40 +0200, jacob navia
<ja***@jacob.remcomp.frwrote in comp.lang.c:
Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.
int main(void)
{
long long a;
char *n;

(char *)a = n;
}

This will fail under lcc-win32, but MSVC and gcc will
accept it. I know that the standard prescribes the behavior
that lcc-win32 uses, but I left that behavior after a big
discussion about this several years ago. I had modified it,
and some people raised hell.
I just tried this with Visual Studio 2005 Express, and indeed you have
to set the warning level to maximum (/W4) to even get it to issue a
misleadingly incorrectly worded error massage:

"warning C4213: nonstandard extension used : cast on l-value"

....but it still produces a 32-bit executable. When I initialize a to
a value and n to NULL, it sets the low 32 bits of a to its
representation of a NULL pointer (0), and leaves the high 32 bits
unchanged.

The only version of gcc that I have installed at the moment is 3.4.2,
(mingw), and it gives me these two diagnostics:

"warning: cast to pointer from integer of different size"
"warning: use of cast expressions as lvalues is deprecated"
What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
What do you do with:

(char *)(3LL + 5LL) = n;

....???
Apparently gcc and msvc are still used, and this doesn't seem
to produce any big problems.
Well, actually it does produce the big problem of continuing to allow
programmers to write incorrect and quite possibly unsafe code. What
happens when they cast a value with a narrower representation to one
with a wider representation?
Thanks in advance for your comments, and I thank all people
that participated in the discussion yesterday.
Personally, I'm against this. If the cast is to a type with more bits
than the original, you risk overwriting memory incorrectly, with all
of the defect and security issues that involves. If the cast is to a
type with more bits than the original, you risk creating an invalid
trap value in the object.

And, of course, if somebody really needs to do this, or at least
thinks that they do, it is perfectly legal to write:

*(char *)(&a) = n;

This is hideously ugly and stands out like a sore thumb, as well it
should.

If you start down this path, you open a can of worms that means you
need to scrutinize all operators that currently yield (r)values rather
than lvalues. Where and why do you stop?

Given:

void func(int *ip);

What should happen with:

int x = 3;
func(&(x + 2));

You could indeed do this, at the expense of turning C into BASIC (or
other languages), that will construct a temporary object for you.

I just don't think the gain is worth the change, especially since
there is a valid way to write a statement that does the same thing.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Jun 25 '07 #19
On Mon, 25 Jun 2007 00:17:39 +0200, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.frwrote:
>Mark McIntyre wrote:
>On Sun, 24 Jun 2007 23:20:03 +0200, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.frwrote:

(of
long long a;
char *n;

(char *)a = n;
)
>>Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.

Because its meaningless in my view. What exactly does the above do?
Moves the contents of n (an address) into the memory locations of a,
with you so far...
>that can hold a pointer is sizeof(void *) <= sizeof(long long);
.... but not here.
The value of n is assigned to a. Ok. If n is larger than *a, there's a
memory overwrite. How does this 'cast' help with this???
>I am not saying that this is nice/the best thing since sliced bread
but that is what it does.
I probably misunderstand, because to me the above is gibberish.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 25 '07 #20
On Mon, 25 Jun 2007 00:25:32 +0200, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.frwrote:
>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....
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 25 '07 #21
On 24 Jun 2007 22:23:51 GMT, in comp.lang.c , ri*****@cogsci.ed.ac.uk
(Richard Tobin) wrote:
>In article <ft********************************@4ax.com>,
Mark McIntyre <ma**********@spamcop.netwrote:
(replying to Jabob's comment)
>>>Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.
>>Because its meaningless in my view.

C constructs are no natural phenomena. They are meaningful if people
assign meaning to them.
Philosophy is all very well...
>And several compilers *have* assigned meaning
to casts as lvalues,
Yes, but the point is in my view that meaning is meaningless.
IYSWIM...
>>What exactly does the above do?

I believe that it's intended to be equivalent to "a = (long long)n'.
As such, it's not very useful.
Quite

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 25 '07 #22
jacob navia wrote:
Keith Thompson wrote:
>jacob navia <ja***@jacob.remcomp.frwrites:
>>Continuing the discussion about casts, I would like to know
your opinions about the hairy subject of casts as lvalues, i.e.

int main(void)
{
long long a;
char *n;
(char *)a = n;
}
This will fail under lcc-win32, but MSVC and gcc will
accept it. I know that the standard prescribes the behavior
that lcc-win32 uses, but I left that behavior after a big
discussion about this several years ago. I had modified it,
and some people raised hell.

What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?
[...]

This extension doesn't seem to me to be particularly useful. The
above would be more clearly written as:

long long a;
char *n;
a = (long long)n;

Granted.

It is clearer but the question is not if this is pleasing but if there
would be any problems (in the sense of contradictions or buggy language
specifications) if casts could be lvalues.
>Another problem with this, as with any extension, is that it
encourages programmers to write non-portable code that depends on it.

Yes, of course. lcc-win32 doesn't even support this extension. But
if I would add support for it, are there any TECHNICAL drawbacks?
I mean, if somebody asks me to support overloading addition
with

int operator+(struct FOO *a,int b);

I would say NO that can't be done because addition of a pointer and
an integer is already used in the language to access the nth element
using a pointer as base, i.e.
struct FOO *p;
p + 6
addresses the sixth element after the element pointed by p. If I would
implement such an extension I would introduce an ambiguity in the
language.

Is that the case with casts as lvalues?
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.

200 : int a
204 : int b

Neither a nor b is initialized. Their values are indeterminate.

a = 1;

The expression a is an lvalue because the compiler knows it's at 200 and
so knows where to store the value 1.

b = a;

The expression b is an lvalue at address 204. The expression a is now
simply the value 1 to be stored in the location defined by lvalue b.

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.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jun 25 '07 #23
Richard Heathfield wrote:
CBFalconer said:
>jacob navia wrote:
>>>
... snip ...
>>>
Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.

A cast requires a destination (i.e. a lvalue) to receive the
converted object.

No, it doesn't. No object is converted by a cast, and casts do not
*require* lvalues to receive their results. 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.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net
--
Posted via a free Usenet account from http://www.teranews.com

Jun 25 '07 #24
CBFalconer said:
Richard Heathfield wrote:
>CBFalconer said:
>>jacob navia wrote:

... snip ...

Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.

A cast requires a destination (i.e. a lvalue) to receive the
converted object.

No, it doesn't. No object is converted by a cast, and casts do not
*require* lvalues to receive their results. 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.

--
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
Jun 25 '07 #25
Richard Heathfield wrote:
CBFalconer said:
>Richard Heathfield wrote:
>>CBFalconer said:
jacob navia wrote:
>
... snip ...
>
Why are casts not lvalues? What TECHNICAL reasons exist for that?
That is my question.

A cast requires a destination (i.e. a lvalue) to receive the
converted object.

No, it doesn't. No object is converted by a cast, and casts do not
*require* lvalues to receive their results. 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? All the elements of the library have to be
available as functions, and macros (if provided) can only mimic a
function call.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net
--
Posted via a free Usenet account from http://www.teranews.com

Jun 26 '07 #26
"Joe Wright" <jo********@comcast.netwrote in message
news:nK******************************@comcast.com. ..
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

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Jun 26 '07 #27
In article <qa********************************@4ax.comJack Klein <ja*******@spamcop.netwrites:
On Sun, 24 Jun 2007 21:13:40 +0200, jacob navia
<ja***@jacob.remcomp.frwrote in comp.lang.c:
....
What are the problems of doing this? I mean not the usual
"the standard says so" but what problems would arise within the
language if this would be accepted?

What do you do with:
(char *)(3LL + 5LL) = n;
...???
More interesing:
char a;
(long *) a = 0;
Or in general, what if a cast changes the representation?
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Jun 26 '07 #28
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.
All the elements of the library have to be
available as functions, and macros (if provided) can only mimic a
function call.
Yes, but the statement I presented is not a function definition. It is
merely a function call.

--
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
Jun 26 '07 #29
CBFalconer <cb********@yahoo.comwrites:
Richard Heathfield wrote:
>CBFalconer said:
>>Richard Heathfield wrote:
CBFalconer said:
jacob navia wrote:
>>
... snip ...
>>
>Why are casts not lvalues? What TECHNICAL reasons exist for that?
>That is my question.
>
A cast requires a destination (i.e. a lvalue) to receive the
converted object.

No, it doesn't. No object is converted by a cast, and casts do not
*require* lvalues to receive their results. 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? All the elements of the library have to be
available as functions, and macros (if provided) can only mimic a
function call.
There's an lvalue in the expression, but not the one that anyone has
mentioned. Assuming c is a declared object, c (the argument of the
cast) is an lvalue; it's just not used in a context that requires an
lvalue, so it's converted to a non-lvalue, yielding the current value
of c. (I don't remember where the standard specifies this
conversion.)

The *parameter* of the toupper function is an object, and a reference
to that object is an lvalue, but any such reference can only be within
the definition of the toupper function; it's not on the line in
question. In the call, we merely have an *argument*, which is just an
expression (that doesn't happen to be an lvalue).

Note that the identifier toupper itself is not an lvalue, since it
designates a function, not an object.

(If toupper is defined as a macro, then the expression to which the
call expands could include any number of lvalues.)

As for the proposed extension, I presume that a cast expression would
be an lvalue if and only if the operand is an lvalue.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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"
Jun 26 '07 #30
Mark McIntyre <ma**********@spamcop.netwrote:
On Mon, 25 Jun 2007 00:25:32 +0200, in comp.lang.c , jacob navia
<ja***@jacob.remcomp.frwrote:
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
Jun 26 '07 #31
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.

Jun 26 '07 #32
Stephen Sprunk wrote:
"Joe Wright" <jo********@comcast.netwrote in message
news:nK******************************@comcast.com. ..
>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.
Jun 26 '07 #33
jacob navia <ja***@jacob.remcomp.frwrites:
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) ks***@mib.org <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"
Jun 26 '07 #34
Keith Thompson wrote:
jacob navia <ja***@jacob.remcomp.frwrites:
>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.
Jun 26 '07 #35
In article <46***********************@free.teranews.com>,
Stephen Sprunk <st*****@sprunk.orgwrote:
> (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.
Jun 26 '07 #36
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
Jun 26 '07 #37
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
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) ks***@mib.org <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"
Jun 26 '07 #38
jacob navia said:
Keith Thompson wrote:
>jacob navia <ja***@jacob.remcomp.frwrites:
<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
Jun 26 '07 #39
Keith Thompson said:
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
>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?
I find my lack of faith disturbing.

--
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
Jun 26 '07 #40
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.
>All the elements of the library have to be available as functions,
and macros (if provided) can only mimic a function call.

Yes, but the statement I presented is not a function definition.
It is merely a function call.
Which, in turn, requires a location to hold a parameter. Hidden.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 26 '07 #41
Richard Heathfield wrote:
>
.... snip ...
>
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.
No it can't. That expression evaluates c twice, and is forbidden
for macro expansions of the std. library (apart from getc).

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 26 '07 #42
Richard Heathfield wrote:
Keith Thompson said:

<snip>
>An *argument* is not an object.

Hear, hear. So we are indeed in agreement after all, it seems.
Nonsense. An argument is always an expression, converted into an
object, which is not accessible before entry to the sub-routine.
At that point it can be treated as any other local object.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net
--
Posted via a free Usenet account from http://www.teranews.com

Jun 26 '07 #43
CBFalconer wrote:
Richard Heathfield wrote:
>Keith Thompson said:

<snip>
>>An *argument* is not an object.
Hear, hear. So we are indeed in agreement after all, it seems.

Nonsense. An argument is always an expression, converted into an
object, which is not accessible before entry to the sub-routine.
At that point it can be treated as any other local object.
That is exactly what I said.

jacob

P.S. But even if i would say
two plus two is four
I guess Mr heathfield would say

NO. It isn't.

Jun 26 '07 #44
CBFalconer said:
Richard Heathfield wrote:
>>
... snip ...
>>
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.

No it can't. That expression evaluates c twice, and is forbidden
for macro expansions of the std. library (apart from getc).
Oops.

How about this:

((__zog = ((unsigned char)c)) == EOF) ? EOF :__toupper[__zog]

--
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
Jun 26 '07 #45
CBFalconer said:
Richard Heathfield wrote:
>Keith Thompson said:

<snip>
>>An *argument* is not an object.

Hear, hear. So we are indeed in agreement after all, it seems.

Nonsense.
I disagree.
An argument is always an expression,
Right.
converted into an object,
Not quite. The value of the expression is *assigned* to an object.

<snip>

--
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
Jun 26 '07 #46
jacob navia said:

<snip>
P.S. But even if i would say
two plus two is four
I guess Mr heathfield would say

NO. It isn't.
Well, it needn't be; for example, in the ring containing only the
numbers 0, 1, 2, 3, 2 + 2 would be 0, not 4 - of course, that's merely
a nit-pick.

But in fact I'm perfectly happy to agree with you when you're right.
It's only when you're wrong that I disagree with you. That is why I
disagree with you so often.

--
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
Jun 26 '07 #47
On Jun 26, 6:15 am, Richard Heathfield <r...@see.sig.invalidwrote:
Oops.

How about this:

((__zog = ((unsigned char)c)) == EOF) ? EOF :__toupper[__zog]
But...

Weren't you trying to show that toupper((unsigned char)c) doesn't
necessarily contain an lvalue with the value of (unsigned char)c ?

--
Mark

Jun 26 '07 #48
mark said:
On Jun 26, 6:15 am, Richard Heathfield <r...@see.sig.invalidwrote:
>Oops.

How about this:

((__zog = ((unsigned char)c)) == EOF) ? EOF :__toupper[__zog]

But...

Weren't you trying to show that toupper((unsigned char)c) doesn't
necessarily contain an lvalue with the value of (unsigned char)c ?
Touche'. (And a good spot. Clearly I lost concentration!)

Okay, this is the Last Chance Saloon, and relies on the implementation
defining EOF as -1 and __toupper having (at least) UCHAR_MAX + 2
entries:

__toupper[1 + ((unsigned char)c)]

--
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
Jun 26 '07 #49
jacob navia wrote On 06/26/07 03:28,:
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)
Nonsense. On the machine in front of me at this
very moment, the result goes into a CPU register (if
an actual function call is made). The chance that
*anything* gets pushed onto a stack is roughly one
in eight.

--
Er*********@sun.com
Jun 26 '07 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

31
by: Jacob | last post by:
It is a common recommendation to use "static_cast<SomeType> someInstance" instead of the traditional infamous "(SomeType) someInstance". Should I use the same practice for simple types, i.e....
47
by: sunglo | last post by:
Some time a go, in a discussion here in comp.lang.c, I learnt that it's better not to use a (sometype **) where a (void **) is expected (using a cast). Part of the discussion boiled down to the...
3
by: ramasubramanian.rahul | last post by:
i was reading soemthing about Lvalues Rvalues and modifiable Lvalues.... i am confused now... like for eg int *y , x ; y = &x ; in the second is x a lvalue or rvalue any pointers on some good...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.