const_cast<char *>(char* const) 不是左值?

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

编译下面的代码时,我在第 3 行收到有关 const_cast 不是左值的结果的错误。这只是一个问题,因为我使用了 gcc 7.x(即使它应该完全符合 C++17 标准)吗?或者根据标准,这确实是无效代码?

下面的代码是触发错误的最小示例。尝试了 gcc 7.1、7.4 和 https://www.onlinegdb.com/online_c++_compiler 并得到了同样的错误。

char* const a = "xyz";
char* b;
const_cast<char*>(a) = b;  // not lvalue error

gcc 给出的精确错误是:"error: lvalue required as left operand of assignment".

注意(忘记添加):该示例与我编写的实际代码无关。这是我提出的一个示例(我认为)是为了测试人们对标准的理解程度而创建的。所以我只对我在问题中提出的问题感兴趣,即这是否是有效代码(以及为什么)。谢谢!

类型char * const a定义了一个指针变量a,不能改变,但指向可以改变的字符。这不是使指针常量的常见用法。

错误告诉您不能更新 a 的值 - 它不是左值,我不认为 const_cast 在这种情况下可以解决这个问题。

您可能是指 const char *a,它允许更改指针本身,但不能更改指向的内容?

一个"lvalue"是一个句法结构,意思是一种可以出现在赋值左边的表达式。您可以赋值给变量、数组组件或字段,但将赋值给其他类型的表达式(例如 x + y = 7;f(x) = 5;)是语法错误。像 const_cast<char*>(a) 这样的函数调用不是一种可以赋值的表达式。

写成 a = const_cast<char*>(b); 在句法上是有效的,其中函数调用出现在赋值的右边。

So I am only interested in precisely what I asked in the question, i.e., whether this is valid code or not

不是。 const_cast 的结果仅在转换为引用类型时是一个 glvalue(左值或 xvalue)。

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

您没有转换为引用类型,因此结果是纯右值;不是你可以分配给的东西。也不要强制转换为引用类型;试图修改声明为 const 的对象会产生未定义的行为。那你的程序又是另一种无效了。

首先,char* const a = "xyz";是非法的。字符串文字具有类型 const char[N] 并将其分配给 char * const 删除字符的常量,这在隐式转换中是非法的。

现在让我们假装一切正常,让我们看看

const_cast<char*>(a) = b

这有两个问题。第一个是 const_cast<char*>(a) 产生右值。对于非 class 类型,您不能分配给右值。您需要 const_cast<char*&>(a) 才能分配左值,这会带来下一个问题。您不能分配给 const 的对象。使用 const_cast 去除 const 并不能解决问题。根据 [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.

即使进行了正确的转换,底层对象仍然是 const,因此您违反了上述条款并具有未定义的行为。