我和IRC的某个人进行过讨论,这个问题出现了。标准允许我们将int
类型的对象更改为char
左值。
int a;
char *b = (char*) &a;
*b = 0;
如果我们知道对齐方式没问题,我们是否可以在相反的方向上这样做?
我看到的问题是,如果将别名规则视为非对称关系,则别名规则不会涵盖以下的简单情况
int a;
a = 0;
原因是,每个对象都包含一系列sizeof(obj)
unsigned char
个对象(称为“对象表示”)。如果我们更改int
,我们将更改部分或全部这些对象。但是,别名规则仅指出我们可以将int
更改为char
或unsigned char
,但不能相反。另一个例子
int a[1];
int *ra = a;
*ra = 0;
3.10 / 15(“包含......的聚合或联合类型”)只描述了一个方向,但这次我们需要另一种方式(“作为元素或非静态数据成员的类型”聚合的类型......“)。
另一个方向是暗示的吗?这个问题也适用于C.
答案 0 :(得分:2)
别名规则只是说明内存中任何给定对象都有一个“有效类型”(C99 6.5.7,加脚注73),对这样一个对象的任何访问都要通过以下方法之一:
const
和restrict
等限定符,以及签名/无符号关系可能会有所不同)当然,高级中没有指定有效类型 - 它只是一个用于指定别名的构造。但目的很简单,就是不要使用两种不同的非字符类型访问同一个对象。
所以答案是,是的,你确实可以走向另一个方向。
答案 1 :(得分:1)
标准(C996.3.2.3§7)将这样的指针转换定义为“就好”,转换指针将指向同一地址。 (除非CPU具有使得无法进行转换的对齐,否则它是未定义的行为。)
也就是说,实际演员阵容本身就很好。如果你开始操纵数据会发生什么......现在这是另一个实现定义的故事。
以下是标准:
“指向对象或不完整类型的指针可能会转换为指向不同对象或不完整类型的指针。如果指定类型的结果指针未正确对齐(57),则行为未定义。否则,当再次转换回来时,结果应该等于原始指针。
当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。结果的连续增量,直到对象的大小,产生指针 到对象的剩余字节。“
“57)一般来说,”正确对齐“这个概念是传递性的:如果指向类型A的指针正确对齐指向类型B的指针,而指针又针对指向类型C的指针正确对齐,那么指向类型A的指针是 正确对齐指向类型C的指针。“
答案 2 :(得分:0)
我觉得我对这个问题感到有些困惑,但是第二和第三个例子是通过一个具有对象类型(在示例中为int
)的左值来访问int。
C ++ 3.10 / 15声明它是第一个可以通过左值访问对象的项目,该左值具有“对象的动态类型”类型。
我在这个问题上有什么误解?