【问题标题】:Why is this one an undefined behaviour? [duplicate]为什么这是一种未定义的行为? [复制]
【发布时间】:2019-12-26 00:30:40
【问题描述】:

在我的 c++ 书中,我刚刚找到了一个代码,书中说存在未定义的行为。

# include <iostream>
using namespace std;

int main( )
{
const char * a = "aaa";
char * b = const_cast<char *>(a);
cout << a << '\n' << b << '\n';
b[0] = 'b'; // here undef. behaviour 
cout << a << '\n' << b << '\n';
}

我不明白为什么。有人知道吗?

【问题讨论】:

  • 你了解const_cast 的本质以及它在这里的作用吗?
  • 无法更改字符串文字。此代码尝试修改字符串文字。因此这是未定义的行为。
  • const int i = 42; int&amp; j = const_cast&lt;int&amp;&gt;(i); j = 0;
  • 简答——因为你修改了常量数据,所以只有当原始数据不是 const 时才允许修改 const cast 后的数据。
  • 如果这本书没有告诉你原因,那它就不是一本很好的书。 Here 是一本不错的书籍。

标签: c++ undefined-behavior


【解决方案1】:

字符串字面量是不可变的,因此它们应该存储在const char * 的变量中,以防止意外尝试更改它们。 const_cast 移除了这层保护,然后b[0] = 'b'; 正在对其执行写入操作。由于它指向的仍然是一个字符串字面量,因此这个写入是未定义的行为。

【讨论】:

  • 挑剔:字符串文字是const char[N],而不是const char *
  • 您可以详细说明可能的原因。例如。如果另一个常量具有相同的文本,则允许编译器重用该字符串。编译器甚至可以生成生成字符串的代码,因此甚至可能没有文本的内存位置。文本可以存储在只读媒体上。
  • @NathanOliver:我只知道一种相关的情况,但这是一种有用的情况:在字符串文字上应用sizeof 运算符将产生比其长度大一的值。这使得定义一个宏来声明像static struct { uint16_t lengh, char dat[sizeof ("" LITERAL "")]} NAME = {sizeof ("" LITERAL ""), LITERAL} NAME; 这样的东西成为可能,但不幸的是,这只能在语句级别完成,而不是表达式级别。
猜你喜欢
  • 2013-09-13
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-24
相关资源
最近更新 更多