l-values and r-values

T

Taras_96

On Dec 13, 6:30 pm, Taras_96 <[email protected]> wrote:
A more interesting case would be:

    Foo f() ;

    Foo b = f() ;

Here, the rvalue is used to initialize the reference
parameter---in other words, it is behaving like an lvalue, or is
immediately converted to an lvalue (depending on how you want to
word it---but a reference is an lvalue, no matter how you look
at it).

Good points ;). This is of course assuming that the c cstrctr takes a
reference, rather than a constant reference (otherwise there wouldn't
be need for the conversion to an l-value, as an r-value can be used to
initialise a constant reference).
The above, except that you don't even need to call a member
function.  Otherwise, of course, the classical:

    std::eek:stringstream().flush() << ...

std::eek:stringstream() is, of course, not an lvalue.  But flush()
returns a reference to it, and a reference is an lvalue.

Also true :)
 
T

Taras_96

Also note that this is a special case; string literals are able to be
converted to non-const just to main compatibility with old code, but
aren't guaranteed to be in a modifiable part of memory. Therefore:

char *blah = "Hello";
blah[0] = 'J';

Is officially undefined. Whereas:

char array[] = "Hello";
char *blah = array;
blah[0] = 'J';

Is perfectly safe.

I don't see how this is safe.. wouldn't it be undefined? You're
effectively casting away the const in the line:

char array [] = "Hello";
 
T

Taras_96

Are you saying that the fact that a literal isn't a constant,
and that when you read "abcd" in the code, it might actually be
"xyz", isn't a misfeature?

--
James Kanze (GABI Software)             email:[email protected]
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Depends on what the definition of 'literal' is ;). If you take the
following definition: 'are invariants whose values are implied by
their representations.', then yes, it is a misfeature. For some reason
I thought (without giving it too much thought) that a 'literal' in
programming talk was a value which is hard coded into the source -
looks like it's a bit more than that.

Taras
 
J

James Kanze

Good points ;). This is of course assuming that the c cstrctr
takes a reference, rather than a constant reference (otherwise
there wouldn't be need for the conversion to an l-value, as an
r-value can be used to initialise a constant reference).

You missed the point. A reference (const or not) is an lvalue.
When you initialize a reference with a temporary (an rvalue),
you have effectively converted the rvalue to an lvalue.
 
J

James Kanze

Also note that this is a special case; string literals are
able to be converted to non-const just to main compatibility
with old code, but aren't guaranteed to be in a modifiable
part of memory. Therefore:
char *blah = "Hello";
blah[0] = 'J';
Is officially undefined. Whereas:
char array[] = "Hello";
char *blah = array;
blah[0] = 'J';
Is perfectly safe.
I don't see how this is safe.. wouldn't it be undefined?
You're effectively casting away the const in the line:
char array [] = "Hello";

No you're not. This is a special case---if you use a string
literal to initialize a char[] (or a char const[]), it is the
equivalent of "{ 'H', 'e', 'l', 'l', 'o', '\0' }". In other
words, it isn't a char const[] at all.
 
T

Taras_96

Taras_96 said:
I don't see how this is safe.. wouldn't it be undefined? You're
effectively casting away the const in the line:
char array [] = "Hello";

No. This is a special syntax to initialise the array of char. What
book are you reading that doesn't explain arrays and their
initialisation? Consider:

int arr[] = { 1,2,3,4,5,6,7,8,9 };

What's 'arr' in your view? If it's an array, how many elements does it
have? What's the type of each element? If it isn't an array, what is it?

Ok, so char array [] = "Hello";

is the initialisation of a array of characters.. which is nothing to
do with string literals.

The original example given by Jason involved two fundamentally
different concepts. The first was initialising a char * to point to a
string literal, the second was the initialisation of a char array. For
some reason I thought they were the same with different syntax (in
hindsight they're obviously not).

Cheers
 
A

Ali Karaali

I want to ask another question that related the topic.

One of the important difference between C and C++ is
prefix ++ operator. The operator doesn't yield an l-value
in C but in C++ it yields a l-value.

I tried to overload the prefix ++ oprator for that class;

class MyInt
{
int m_i;

friend ostream & operator<< (ostream &, const MyInt &);

public:

MyInt(int i)
:
m_i(i)
{}

MyInt(const MyInt & r)
{
m_i = r.m_i;
}

MyInt & operator+= (const MyInt & anoth)
{
m_i += anoth.m_i;
return *this;
}

MyInt operator++ (int);

MyInt & MyInt::eek:perator ++()
{
return *this += 1;
}
};

MyInt MyInt::eek:perator++ ( int )
{
MyInt m_r( *this );
++*this;

return m_r;
}

MyInt operator+ (const MyInt & lefts, const MyInt & rights)
{
MyInt result = lefts;
result += rights;
return result;

// Or
// return MyInt( lefts ).operator+= ( rights );
}

int main()
{
MyInt myi( 5 );

// I am expecting error bu doesn't happen. Why?
myi++ = 10;

cout << myi;
}
 
T

Taras_96

Taras_96 said:
Taras_96 wrote:
I don't see how this is safe.. wouldn't it be undefined? You're
effectively casting away the const in the line:
char array [] = "Hello";
No.  This is a special syntax to initialise the array of char.  What
book are you reading that doesn't explain arrays and their
initialisation?  Consider:
     int arr[] = { 1,2,3,4,5,6,7,8,9 };
What's 'arr' in your view?  If it's an array, how many elements does
it have?  What's the type of each element?  If it isn't an array,
what is it?
Ok, so char array [] = "Hello";
is the initialisation of a array of characters.. which is nothing to
do with string literals.

That's not entirely accurate.  The array is initialised with a string
literal, as everybody can see.  The array contains a C string (since
the elements are char, they are sequential, and terminated with a null
char).  So, it's not "nothing", really.

It's nothing?? :). Surely it's an array of chars, as you said, the
array contains a C string, which is simply an array of chars
terminated with a null char.
 
J

James Kanze

Ali said:
One of the important difference between C and C++ is prefix
++ operator. The operator doesn't yield an l-value in C but
in C++ it yields a l-value.
I tried to overload the prefix ++ oprator for that class;
class MyInt
{ [...]
MyInt operator++ (int);
MyInt & MyInt::eek:perator ++()
{
return *this += 1;
}
};
MyInt MyInt::eek:perator++ ( int )
{
MyInt m_r( *this );
++*this;
return m_r;
}
// I am expecting error bu doesn't happen. Why?
myi++ = 10;
You're assigning an integer to a temporary. The temporary
will go away as soon as the full expression is evaluated. It
will be destroyed with the value 10. Why would there be an
error?
BTW, you stated that you "tried to overload the prefix ++
oprator" while the class here has the *postfix* operator++
overloaded.

His class defined both, but his example effectively does use the
postfix operator. If myi were a built-in type, the expression
would be illegal, since assignment requires an lvalue for the
left operand, and the result of post-fix ++ is not an lvalue.
The difference here is that a user defined assignment operator
is a member function, and you can call a member function on an
rvalue. For most operators which require lvalues, the solution
is to declare the operator as a non-member, taking a non-const
reference---an rvalue cannot be used to initialize a non-const
reference. This isn't possible in the case of operator=,
however, since operator= must be a member.

Note that you don't really need any user defined operators at
all for this problem to manifest itself:

struct S { int i ; } ;
S f() ;

// ...
S s = { 42 } ;
f() = s ;

This won't compile in C, but is perfectly legal C++.
 

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,780
Messages
2,569,608
Members
45,241
Latest member
Lisa1997

Latest Threads

Top