a basic question,need help

J

jackie

i know that in c plus plus,++x returns l-value while x++ returns r-
value,but what is the situation in c,are both ++x and x++ return r-
value? i don't know how C99 defines it,thx.
 
T

Tommy

[cuitao@mytest c]$ vi pp.c

#include <stdio.h>
int main()
{
int x=10;
x=20;
printf("\nx=%d\n",x);

return 0;
}
~
~
~
"pp.c" 9L, 99C written
[cuitao@mytest c]$
[cuitao@mytest c]$
[cuitao@mytest c]$ cc ./pp.c -o ./pp
[cuitao@mytest c]$
[cuitao@mytest c]$ ./pp

x=20
[cuitao@mytest c]$


[cuitao@mytest c]$ vi pp.c

#include <stdio.h>
int main()
{
int x=10;
x++=20;
printf("\nx=%d\n",x);

return 0;
}
~
~
~
"pp.c" 9L, 101C written
[cuitao@mytest c]$
[cuitao@mytest c]$
[cuitao@mytest c]$ cc ./pp.c -o ./pp
../pp.c: In function `main':
../pp.c:5: error: invalid lvalue in assignment





[cuitao@mytest c]$ vi pp.c

#include <stdio.h>
int main()
{
int x=10;
++x=20;
printf("\nx=%d\n",x);

return 0;
}
~
~
~
"pp.c" 9L, 101C written
[cuitao@mytest c]$ cc ./pp.c -o ./pp
../pp.c: In function `main':
../pp.c:5: error: invalid lvalue in assignment
[cuitao@mytest c]$
 
I

Ian Collins

Eric said:
In C (all versions), neither ++x nor x++ is an lvalue.
I'm surprised to hear that this is different in C++, because
it makes no sense to me. Is

int x = 42;
++x = 97;

legal in C++?

No.
 
C

CBFalconer

jackie said:
i know that in c plus plus,++x returns l-value while x++ returns
r- value,but what is the situation in c,are both ++x and x++
return r- value? i don't know how C99 defines it,thx.

You're wrong. Illustrative snippet:

volatile int x = 123;
int y;

y = x;
if ((y == x++) && ((y + 1) == x)) puts("Correct x++");
else puts("Bad system");

y = x;
if (((y + 1) == ++x) && ((y + 1) == x)) puts("Correct ++x");
else puts("Bad system");

The operator has nothing to to with lvalues and rvalues. Same in
C++. Note that in the snippet the first phrase in the test (before
the &&) is completed before the 2nd phase is begun.
 
D

Daniel Pitts

Ian said:
Sure it is:

class foo {
public:
foo(int x) {
}
foo &operator=(int x){}
};
foo &operator++(foo &x) {
return x;
}

int main() {
#define int foo
int x = 72;
++x = 32;
}
 
C

CBFalconer

Keith said:
.... snip ...


Illustrative of what?

Of the behaviour of x++ and ++x.
What is the point of declaring x volatile?

That ensures that x is accessed for each equality test. That way
it can't be carried along in a working register.
Certainly it does.

In both C and C++, the operand of a prefix or postfix "++" must be a
modifiable lvalue. In C, the result of either operator is not an
lvalue; in C++, one is an lvalue and one isn't.

In any case, your code snippet is equally valid in either C or C++,
and would behave in exactly the same way even if both prefix and
postfix "++" yielded lvalues; you never use them in a context that
requires an lvalue.

So what was your point again?

To demonstrate the actions of x++ and ++x, and their difference.
 
J

jackie

Just what is it that you think he's wrong about?

(I'm assuming jackie is a "he"; apologies if I'm mistaken.)

In C++, the result of ``++x'' is an lvalue, and the result of ``x++''
is not an lvalue, so he's right about that; it's off-topic, but a
perfectly reasonable introduction to his question.

The rest of the post was a question, which can hardly be wrong, and a
statement that he doesn't know something, which you can hardly assume
is wrong.


Illustrative of what?




What is the point of declaring x volatile?


Certainly it does.

In both C and C++, the operand of a prefix or postfix "++" must be a
modifiable lvalue.  In C, the result of either operator is not an
lvalue; in C++, one is an lvalue and one isn't.

In any case, your code snippet is equally valid in either C or C++,
and would behave in exactly the same way even if both prefix and
postfix "++" yielded lvalues; you never use them in a context that
requires an lvalue.

So what was your point again?

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



u're right,i'm a "he". ^-^
and i think u have already give me ur answer,that's both ++x and x++
return r-value in c,do u mean that? thx for ur help
 
J

James Kuyper

CBFalconer said:
Of the behaviour of x++ and ++x.

To demonstrate the actions of x++ and ++x, and their difference.

The question was about the lvalue-ness of x++ and ++x; what does your
example have to do with that question?
 
S

Spiro Trikaliotis

Hello,

Eric said:
In C (all versions), neither ++x nor x++ is an lvalue.
I'm surprised to hear that this is different in C++, because
it makes no sense to me.
[...]

I was surprised, too, when I read it lately in the German C++ newsgroup
de.comp.lang.iso-c++. To be more precise, there, it was asked why the assignment
operator returns an lvalue in C++, but the reasons should be the same
for the pre-increment operator.

If you can read German: The thread starts with MessageId:
<[email protected]>.

(Google Groups link to the whole thread:
http://groups.google.com/group/de.c...2/3078d39363ca2dba?lnk=st&q=#3078d39363ca2dba)

In Message-ID: <[email protected]>, the author
cites Andrew Koenig (from memory) about the reasons for this change
(Google-Groups:
http://groups.google.com/group/de.comp.lang.iso-c++/msg/06a8c53a5db4d274?dmode=source)


In short: Assume that you have two functions

T f(T y)
{
T x;

x=y;
return x;
}

and

T g(T y)
{
T x;

return x=y;
}

with T being some typedef'd type.

Both return statements are completely equivalent in C.


Now, change the prototype of f and g to return a reference (which is
only possible in C++, of course), that is,

T & f(T y)
and
T & g(T y)

Now, with C semantics (the assignment is an r-value), in f(), the return
would handle an l-value, while in g(), it would handle an r-value. This
is problematic, as an r-value must be copied before it can be returned
as a reference,
while an l-value does not need to be copied. If T is not a simple type
like ints, but complex structures (matrices with some 1000s of elements,
for example), the difference can be enormous.

The same problem occurs if x=y is replaced with ++x in both functions.


So, this change is somehow related to the references in C++. In fact, it
is needed in order to let C++ be more C-like with respect to efficiency.
Note, that I did not look at the disadvantages this might have.

Regards,
Spiro.

"Anybody who would spend considerable effort emulating a C64 is not
particularly sane to begin with; it is unreasonable to expect them to produce
sane software."
("asuffield" in http://forums.thedailywtf.com/forums/p/7199/134136.aspx)
 
C

CBFalconer

James said:
The question was about the lvalue-ness of x++ and ++x; what does
your example have to do with that question?

Well, for one thing you can see immediately that x++ can't have an
lvalue. There is nothing holding that value, apart from the
reference y.
 
C

christian.bau

I'm surprised to hear that this is different in C++, because
it makes no sense to me. Is

int x = 42;
++x = 97;

legal in C++? If so, what is the value of x afterwards?
(Actually, you can disregard the second question: If the
answer to the first is anything other than "No," I don't
want to know anything more about C++.)

It is syntactically legal, but it invokes undefined behaviour same as
it would in C if ++x was an lvalue (the same object is modified twice
without intervening sequence point). Something that is legal and makes
a bit of sense would be:

int x = 42;
int *p = &++x;

This will give you x = 43, and p = &x. There is motivation for this
because of "references" in C++. If you have a C++ function

int f (int& x) { return x++; }

then you can call

int x = 42;
int y = f (++x);

which will increase x by one, pass x "by reference" to the function f
which is rather the same as passing the address; f will increase x in
the caller (because it has a reference to it) and return the value
before the incremenent. Effectively this will set x to 44 and y to 43,
and there is no undefined behavior because there are plenty of
sequence points.
 
K

Keith Thompson

jackie said:
u're right,i'm a "he". ^-^
and i think u have already give me ur answer,that's both ++x and x++
return r-value in c,do u mean that? thx for ur help

Yes, both ++x and x++ yield a non-lvalue in C. (You can call that an
"rvalue", but C doesn't use the term except in a single footnote.)

Incidentally, silly abbreviations like "u", "ur", and "thx" are
frowwned upon here. Please take the time to spell out simple words
like "you", "your", and "thanks". Not everyone here speaks English as
a native language -- and those of us who do generally prefer to read
actual English.

Also, when you post a followup, it's rarely necessary to quote the
entire parent article. Delete any quoted material that's not relevant
to your followup, leaving just enough so that your article makes sense
to someone who hasn't seen the parent. In particular, don't quote
signatures unless you're actually commenting on them.

Thx. :cool:}
 
J

jameskuyper

CBFalconer said:
Well, for one thing you can see immediately that x++ can't have an
lvalue. There is nothing holding that value, apart from the
reference y.

Actually, it is ++x, not x++, which is an lvalue in C++, and your code
does nothing to demonstrate that "There is nothing holding" the value
of ++x, because you code makes no use of ++x in a context that
requires an lvalue.
The example provided by Daniel Pits does use ++x in a context that
requires an lvalue. The fact that his code compiles and works as he
expected it to work demonstrates that jackie was in fact correct in
saying that ++x is an lvalue in C++, your assertions to the contrary
notwithstanding.

Actually, as a demonstration, Daniel's code could be improved upon. It
would be clearer what the lvalued-ness of ++x means in C++, if his foo
class had contained a non-static data member that participated in
operator++() and operator=() in a non-trivial fashion. I assure you
that adding such a data member would not prevent the code from
working. If he had done so, it would have been quite clear that there
is indeed something "holding that value". The "something" is what C++
calls an temporary object.

The fact that C cannot usefully make ++x an lvalue is due the fact
that C structs cannot have member functions. The fact that C has no
need to make ++x an lvalue is mainly due to the fact that C doesn't
have operator overloads. It's not because it would be impossible to
make ++x an lvalue in C; it would have been just as feasible for C to
introduce the concept of a temporary object.
 
K

Keith Thompson

CBFalconer said:
... snip ...

The above "... snip ..." includes you claiming that the original
poster is wrong, and me asking you what you think he's wrong about.

So, just what do you think the original poster was wrong about? As
far as I can tell, he was quite correct.
Of the behaviour of x++ and ++x.

Not of any behavior relevant to the question.
That ensures that x is accessed for each equality test. That way
it can't be carried along in a working register.

Why would storing the value of x in a working register be a problem?
The behavior of your code snippet is well defined, and exactly the
same, with or without the "volatile" (unless the accesses to x are
intended to have some side effect you're not telling us about, but
that doesn't seem likely).

To put it another way, why not make y volatile as well?
To demonstrate the actions of x++ and ++x, and their difference.

But that wasn't what anybody was asking about. The question was
whether ++x or x++ yields an lvalue. That's a perfectly legitimate
question, to which an answer of "No" would have been entirely correct
and sufficient.
 
A

Antoninus Twink

Well, for one thing you can see immediately that x++ can't have an
lvalue. There is nothing holding that value, apart from the
reference y.

My god, you really have gone off into la-la land in your dotage, haven't
you? Your last sentence doesn't make a bit of sense. And y is not a
reference in your code (as you're normally the first to say, C doesn't
have references).
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top