简体   繁体   中英

const_cast<char *>(char* const) not lvalue?

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 type T . If T 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 using const_cast are listed below. No other conversion shall be performed explicitly using const_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM