通过指向int的指针对char数组进行别名是否合法? [英] Is it legal to alias a char array through a pointer to int?
问题描述
我知道该标准明确允许以下内容:
I know that the following is explicitly allowed in the standard:
int n = 0;
char *ptr = (char *) &n;
cout << *ptr;
那呢?
alignas(int) char storage[sizeof(int)];
int *ptr = (int *) &storage[0];
*ptr = 0;
cout << *ptr;
本质上,我在问别名规则是否允许通过指向另一种类型的指针来访问字符序列.如果可能,我希望引用该标准的各个部分,以指示一种或另一种方式.
Essentially, I'm asking if the aliasing rules allow for a sequence of chars to be accessed through a pointer to another type. I'd like references to the portions of the standard that indicate one way or another if possible.
该标准的某些部分使我产生了冲突; (3.10.10)似乎表明,假设storage
的动态类型不是int
,这将是未定义的行为.但是,动态类型的定义对我来说还不清楚,并且std::aligned_storage
的存在会让我相信 是可能的.
Some parts of the standard have left me conflicted; (3.10.10) seems to indicate it would be undefined behavior on the assumption that the dynamic type of storage
is not int
. However, the definition of dynamic type is unclear to me, and the existence of std::aligned_storage
would lead me to believe that this is possible.
推荐答案
代码int *ptr = (int *) &storage[0]; *ptr = 0;
通过违反严格的别名规则(C ++ 14 [basic.lval]/10)导致未定义的行为
The code int *ptr = (int *) &storage[0]; *ptr = 0;
causes undefined behaviour by violating the strict aliasing rule (C++14 [basic.lval]/10)
所访问的对象的类型为char
,但用于访问的glvalue的类型为int
.
The objects being accessed have type char
but the glvalue used for the access has type int
.
char
的对象的动态类型"仍为char
. (动态类型仅在派生类型与静态类型不同班级). C ++也没有C的有效类型"的等效项,它允许通过使用赋值运算符到malloc的空间来创建"类型化的对象.
The "dynamic type of the object" for a char
is still char
. (The dynamic type only differs from the static type in the case of a derived class). C++ does not have any equivalent of C's "effective type" either, which allows typed objects to be "created" by using the assignment operator into malloc'd space.
关于正确使用std::aligned_storage
的方法,应该使用newplace新方法在存储中创建一个对象.新的placement-new的使用被认为可以结束char
(或任何其他)对象的生命周期,并创建指定类型的新对象(动态存储持续时间),并重新使用相同的存储.这样就不会出现严格的混叠冲突.
Regarding correct use of std::aligned_storage
, you're supposed to then use placement-new to create an object in the storage. The use of placement-new is considered to end the lifetime of the char
(or whatever) objects, and create a new object (of dynamic storage duration) of the specified type, re-using the same storage. Then there will be no strict aliasing violation.
您可以对char数组执行相同的操作,例如:
You could do the same thing with the char array, e.g.:
alignas(int) char storage[sizeof(int)];
int *ptr = new(storage) int;
*ptr = 0;
cout << *ptr;
请注意,内置类型int
不需要伪析构函数调用或delete
.如果使用具有非平凡初始化的类类型,则需要这样做. 链接到进一步的阅读内容
Note that no pseudo-destructor call or delete
is required for built-in type int
. You would need to do that if using a class type with non-trivial initialization. Link to further reading
这篇关于通过指向int的指针对char数组进行别名是否合法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!