When compiling the code below, I am getting an error on line 3 about the result of const_cast not being an lvalue. Is this only a problem because I used gcc 7.x (even though it is supposed to be fully C++17 compliant)? Or is this indeed invalid code according to the standard?
The code below is a minimal example that triggers the error. Tried gcc 7.1, 7.4, and also https://www.onlinegdb.com/online_c++_compiler and got the same error.
char* const a = "xyz";
char* b;
const_cast<char*>(a) = b; // not lvalue error
The precise error gcc gives is: "error: lvalue required as left operand of assignment".
NOTE (forgot to add): the example has nothing to do with actual code I would ever write. It is an example I came about which (I presume) was created to test how well people understand the standard. So I am only interested in precisely what I asked in the question, ie, whether this is valid code or not (and why). Thx!
So I am only interested in precisely what I asked in the question, ie, whether this is valid code or not
It's not. The result of const_cast
is a glvalue (lvalue or xvalue) only when casting to a reference type.
[expr.const.cast] (emphasis mine)
1 The result of the expression
const_cast<T>(v)
is of typeT
. IfT
is an lvalue reference to object type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed on the expression v. Conversions that can be performed explicitly usingconst_cast
are listed below. No other conversion shall be performed explicitly usingconst_cast
.
You don't cast to a reference type, so the result is a prvalue; not something you may assign to. And don't go casting to a reference type either; attempting to modify an object declared as const gives undefined behavior. Your program will be another sort of invalid then.
First, char* const a = "xyz";
is illegal. a string literal has the type const char[N]
and assign it to a char * const
removes the constness of the characters which is illegal in an implicit cast.
Now lets pretend that it's fine and lets look at
const_cast<char*>(a) = b
This has two issues. The first is that const_cast<char*>(a)
results in a rvalue. For non-class types you cannot assign to rvalues. You would need const_cast<char*&>(a)
in order to have an lvalue to assign to, and that brings up the next problem. You can't assign to an object that is const
. Stripping away the const
using const_cast
doesn't fix the issue. It is still not allowed per [dcl.type.cv]/4
Any attempt to modify ([expr.ass], [expr.post.incr], [expr.pre.incr]) a const object ([basic.type.qualifier]) during its lifetime ([basic.life]) results in undefined behavior.
Even with the proper cast, the underlying object is still const
so you violate the above clause and have undefined behavior.
The type char * const a
defines a pointer variable a
, which cannot be changed, but points to characters that can be changed. This is not a common use to make the pointer constant.
The error is telling you that you cannot update the value of a
- it's not an lvalue, and I don't believe that const_cast
gets around that in this case.
Could you possibly mean const char *a
, which allows the pointer itself to be changed, but not the things pointed to?
An "lvalue" is a syntactic construct, meaning a kind of expression that can appear on the left of an assignment. You can assign to a variable, or an array component, or a field, but it's a syntax error to write an assignment to other kinds of expression such as x + y = 7;
or f(x) = 5;
. A function call such as const_cast<char*>(a)
is not a kind of expression which can be assigned to.
It would be syntactically valid to write a = const_cast<char*>(b);
, where the function call appears on the right of the assignment.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.