C++ 通过指向int的指针为char数组别名合法吗?

C++ 通过指向int的指针为char数组别名合法吗?,c++,language-lawyer,strict-aliasing,C++,Language Lawyer,Strict Aliasing,我知道标准中明确允许以下内容: int n = 0; char *ptr = (char *) &n; cout << *ptr; int n=0; char*ptr=(char*)&n; cout在这里,union结构可能很有用 union类似于struct,不同之处在于union的所有元素占用相同的存储区域 换句话说,它们是“看待同一事物的不同方式”,就像FORTRAN的等价性声明一样。因此,例如: union { int foo; float bar;

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

int n = 0;
char *ptr = (char *) &n;
cout << *ptr;
int n=0;
char*ptr=(char*)&n;

cout在这里,
union
结构可能很有用

union
类似于
struct
,不同之处在于
union
的所有元素占用相同的存储区域

换句话说,它们是“看待同一事物的不同方式”,就像FORTRAN的
等价性
声明一样。因此,例如:

union {
  int   foo;
  float bar;
  char  bletch[8];
}

提供了三种完全不同的方法来考虑相同的存储区域。(联合体的存储大小是其最长组件的大小。)

foo
bar
bletch
都是同一存储的同义词

union
通常与
typedef
一起使用,如本StackOverflow文章所示:.

代码
int*ptr=(int*)和存储[0]*ptr=0违反严格的别名规则(C++14[basic.lval]/10),导致未定义的行为

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

char
的“对象动态类型”仍然是
char
。(仅在派生类的情况下,与静态类型不同)。C++没有任何等价于C的“有效类型”,它允许类型化对象通过使用赋值操作符到Malc空间中被“创建”。
关于正确使用
std::aligned_存储
,您应该使用placement new在存储中创建一个对象。使用placement new可以结束
char
(或其他)对象的生存期,并创建指定类型的新对象(动态存储持续时间),重新使用相同的存储。这样就不会有严格的别名冲突

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

alignas(int) char storage[sizeof(int)];
int *ptr = new(storage) int;
*ptr = 0;
cout << *ptr;
alignas(int)字符存储[sizeof(int)];
int*ptr=新(存储)int;
*ptr=0;
库特
写入int,因此它是对int的访问,具有int类型的左值,因此部分代码可以


演员阵容在道德上是好的,但是C/C++标准文本没有清楚地描述演员阵容、指针或任何基本内容。

投否决票的人可以留下评论吗?我不知道你是否可以这样做,但标准定义了以你尝试的方式访问a中的变量,我没有投票,但是,如果你要求参考标准,我希望你展示你自己的研究,引用你认为相关的部分,并描述你自己不确定的结论。@chbaker0查看我上面给出的链接,它看起来像是一个示例实现(希望符合标准)做与你现在做的几乎相同的事情here@user2079303好的,我将在我的研究中添加一个让我感到矛盾的问题:C++中有这个问题,根据这个规则在C++中是不合法的(但是它是C)。这个词是相同的。C++不允许通过联合进行类型双关。您只能读取最近分配给成员的内容。哦,foo。。。你是多么正确。。。我很难过*(…(“键入双关语”…不知何故,我以前从未听说过这个词。但是,我喜欢它。)@M.M“您只能读出最近分配给成员的内容”这也不是真的。第二部分是我误解的核心;我没有意识到对象类型是通过使用placement
new
建立的。因此这意味着使用
malloc
然后将结果内存用作
int
char
以外的任何其他原语也是未定义的少做placement new?@chbaker0是的,这不是很广为人知;省略placement new和执行严格的别名冲突似乎最有效(或全部有效)大多数时候,很多人只是这样做,要么不知道问题所在,要么不关心标准。根据标准-这是正确的,在写入malloc空间之前,必须在malloc空间上使用新的位置。@curiousguy标准不支持你的说法。说声明字符数组使一个无限多的对象。这个线程是关于标准实际上说了什么,而不是你希望它说什么。他们确实清楚地描述了它,你只是似乎不同意标准所说的含义,所以你假装它没有说。@M.M“他们确实清楚地描述了它”我很高兴了解到这一点。请查看并回答我关于指针的许多问题:@M.M这里的含义是,直到最近,对联合的任何使用都是未定义的,这是非常愚蠢的。
alignas(int) char storage[sizeof(int)];
int *ptr = new(storage) int;
*ptr = 0;
cout << *ptr;
*ptr = 0;