Topic: Is this a bug of the C++ standard?


Author: xmllmx <xmllmx@gmail.com>
Date: Sat, 18 Aug 2007 19:03:30 CST
Raw View
In 5.1.2 of the C++ standard, the standard states: "A string literal
is an lvalue; all other literals are rvalue."

It is so strange to me! To verify this rule, I use VS 2005 to compile
the following code:

const_cast<char*>("c") = "abcd";

the compiler tells me:

error C2106: '=' : left operand must be l-value

I can't make me believe the standard is wrong, who can give me an
explanation?

Thanks in advance.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: jdennett@acm.org (James Dennett)
Date: Sun, 19 Aug 2007 06:44:27 GMT
Raw View
xmllmx wrote:
> In 5.1.2 of the C++ standard, the standard states: "A string literal
> is an lvalue; all other literals are rvalue."
>
> It is so strange to me! To verify this rule, I use VS 2005 to compile
> the following code:
>
> const_cast<char*>("c") = "abcd";
>
> the compiler tells me:
>
> error C2106: '=' : left operand must be l-value
>
> I can't make me believe the standard is wrong, who can give me an
> explanation?

The cast gives an rvalue, as it is not a cast to a reference
type.  You're attempting to assign to a temporary of built-in
type, which is not allowed (and makes no sense in any
case).

Arrays are (somewhat) unusual in that they are non-assignable
lvalues; you can take their address, but you can't assign to an
array.

-- James

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: xmllmx <xmllmx@gmail.com>
Date: Sun, 19 Aug 2007 08:15:54 CST
Raw View
Thank you, James.

But I'm still unclear.

"Hello" = 0; // Is this allowed?

If a string literal is not assignable, why should the standard define
such an odd rule? That's just what makes me confused.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: jackklein@spamcop.net (Jack Klein)
Date: Sun, 19 Aug 2007 15:37:29 GMT
Raw View
On Sat, 18 Aug 2007 19:03:30 CST, xmllmx <xmllmx@gmail.com> wrote in
comp.std.c++:

> In 5.1.2 of the C++ standard, the standard states: "A string literal
> is an lvalue; all other literals are rvalue."

There are two kinds of lvalues in C++ (and C), modifiable lvalues and
unmodifiable lvalues.  Look at 5.17 for the assignment operators, "All
require a modifiable lvalue as their left operand, and the type of an
assignment expression is that of its left operand."  The term
"modifiable lvalue" is also used definitions of the pre- and post-
increment and decrement operators.

Note also 3.10 paragraph 14:  "If an expression can be used to modify
the object to which it refers, the expression is called modifiable. A
program that attempts to modify an object through a nonmodifiable
lvalue or rvalue expression is ill-formed."

The rest of 3.10 is recommended for understanding rvalues, modifiable
lvalues, and nonmodifiable lvalues.

> It is so strange to me! To verify this rule, I use VS 2005 to compile
> the following code:
>
> const_cast<char*>("c") = "abcd";
>
> the compiler tells me:
>
> error C2106: '=' : left operand must be l-value
>
> I can't make me believe the standard is wrong, who can give me an
> explanation?

The standard is not wrong, but there are a large number of compilers
which have given sloppy, inaccurate diagnostics for many, many years.
Visual C++ is among them.  If their error said "left operand is not a
modifiable lvalue", it would be technically correct.

An array is most certainly an lvalue, but you can't assign to it
either.

--
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

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: francis.glassborow@btinternet.com (Francis Glassborow)
Date: Sun, 19 Aug 2007 15:38:04 GMT
Raw View
James Dennett wrote:
> xmllmx wrote:
>> In 5.1.2 of the C++ standard, the standard states: "A string literal
>> is an lvalue; all other literals are rvalue."
>>
>> It is so strange to me! To verify this rule, I use VS 2005 to compile
>> the following code:
>>
>> const_cast<char*>("c") = "abcd";
>>
>> the compiler tells me:
>>
>> error C2106: '=' : left operand must be l-value
>>
>> I can't make me believe the standard is wrong, who can give me an
>> explanation?
>
> The cast gives an rvalue, as it is not a cast to a reference
> type.  You're attempting to assign to a temporary of built-in
> type, which is not allowed (and makes no sense in any
> case).
>
> Arrays are (somewhat) unusual in that they are non-assignable
> lvalues; you can take their address, but you can't assign to an
> array.
>
In addition the type of "c" is array of two charand you can only const_
cast to a different cv qualification of the same underlying type.


--
Note that robinton.demon.co.uk addresses are no longer valid.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: brok@spam-trap-cop.net (Bronek Kozicki)
Date: Sun, 19 Aug 2007 22:43:04 GMT
Raw View
xmllmx wrote:
> If a string literal is not assignable, why should the standard define
> such an odd rule? That's just what makes me confused.

see here:

   template <size_t Size> void foo(const char (&t) [Size])
   {
     // ... operate on a literal of length Size including NUL
   }

   foo("abc"); // calls template<> void foo(const char (&t) [4]);

here t is
   a reference to
     an array of
       const char and
         size Size.
Please note: a reference, not reference to const. There is no such thing
as const array - all arrays are non-modifiable, but this property is
sometimes taken as granted and not really looked at (probably because it
does not extend onto their content). This means that foo can be only be
called with an lvalue and not with an rvalue. Thanks to discussed rule,
above code works as expected. Otherwise above would trigger an error (an
attempt to bind reference to non-const to rvalue) and there would be no
way to pass a string literal to foo - as there is no way to express "a
reference to const array".


B.

--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]