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

时间:2019-10-31 18:46:53

标签: c++ language-lawyer c++17 lvalue const-cast

当编译下面的代码时,我在第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给出的精确错误是:“错误:左值必须作为赋值的左操作数”。

注意(忘记添加):该示例与我曾经写过的实际代码无关。这是我想到的一个示例,该示例的创建是为了测试人们对标准的理解程度。因此,我只对我在问题中提出的确切内容感兴趣,即这是否是有效的代码(以及原因)。谢谢!

4 个答案:

答案 0 :(得分:3)

  

所以我只对我在问题中所问的内容感兴趣,即这是否是有效代码

不是。仅当转换为引用类型时,const_cast的结果才是glvalue(左值或x值)。

  

[expr.const.cast] (强调我的意思)

     

1表达式const_­cast<T>(v)的结果为类型   T。如果T是对对象类型的左值引用,则结果为   左值如果T是对对象类型的右值引用,则结果是   xvalue; 否则,结果为prvalue ,然后   左值到右值,数组到指针和函数到指针标准   转换是针对表达式v执行的。   下面列出了使用const_­cast显式执行的操作。没有别的   转换应使用const_­cast明确执行。

您不强制转换为引用类型,因此结果为prvalue;不是您可以分配给的东西。而且也不要强制转换为引用类型;尝试修改声明为const的对象会产生未定义的行为。那么您的程序将是另一种无效的程序。

答案 1 :(得分:3)

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

现在让我们假装没问题,然后看看

const_cast<char*>(a) = b

这有两个问题。首先是const_cast<char*>(a)产生一个右值。对于非类类型,您不能分配给右值。您需要const_cast<char*&>(a)才能分配一个左值,这带来了下一个问题。您无法分配给const的对象。使用const剥离const_cast并不能解决问题。根据{{​​3}}

仍然不允许
  

在生存期([basic.life.qualifier])中修改const对象([basic.type.qualifier])的任何尝试([expr.ass],[expr.post.incr],[expr.pre.incr]) ])导致未定义的行为。

即使使用正确的强制转换,基础对象仍然是const,因此您违反了上述子句并具有未定义的行为。

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

“左值”是一种语法构造,表示一种可出现在作业左侧的表达。您可以分配给变量,数组组件或字段,但是将分配写入其他类型的表达式(例如x + y = 7;f(x) = 5;)是语法错误。诸如const_cast<char*>(a)之类的函数调用不是一种可以分配给它的表达式。

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