通过指向int的指针对char数组进行别名是合法的吗?

chb*_*er0 10 c++ strict-aliasing language-lawyer

我知道标准中明确允许以下内容:

int n = 0;
char *ptr = (char *) &n;
cout << *ptr;
Run Code Online (Sandbox Code Playgroud)

那这个呢?

alignas(int) char storage[sizeof(int)];
int *ptr = (int *) &storage[0];
*ptr = 0;
cout << *ptr;
Run Code Online (Sandbox Code Playgroud)

本质上,我问的是,别名规则是否允许通过指向另一种类型的指针访问一系列字符.我想参考标准的部分,如果可能的话,表明这种或那种方式.

标准的某些部分让我感到矛盾; (3.10.10)似乎表明在假设动态类型storage不是的情况下它将是未定义的行为int.然而,动态类型的定义对我来说并不清楚,而且存在std::aligned_storage会让我相信这可能的.

M.M*_*M.M 5

代码int *ptr = (int *) &storage[0]; *ptr = 0;通过违反严格别名规则导致未定义的行为(C++ 14 [basic.lval]/10)

被访问的对象具有类型,char但用于访问的glvalue具有类型int.

a的"动态类型的对象" char仍然是char.(动态类型仅与派生类的静态类型不同).C++也没有任何等效的C"有效类型",它允许通过将赋值运算符用于malloc'd空间来"创建"类型化对象.


关于正确使用std::aligned_storage,你应该使用placement-new在存储中创建一个对象.使用placement-new被认为是结束char(或任何)对象的生命周期,并创建指定类型的新对象(动态存储持续时间),重新使用相同的存储.然后就没有严格的别名违规.

您可以使用char数组执行相同的操作,例如:

alignas(int) char storage[sizeof(int)];
int *ptr = new(storage) int;
*ptr = 0;
cout << *ptr;
Run Code Online (Sandbox Code Playgroud)

请注意,没有伪析构函数调用或delete内置类型是必需的int.如果使用具有非平凡初始化的类类型,则需要这样做.链接到进一步阅读

  • @curiousguy该标准不支持您的声明.实际上,声称一个char数组实际上有效地构成了无数个对象是荒谬的.这个主题是关于标准实际说的内容,而不是你希望的内容. (2认同)