1

我在 IRC 上与某人进行了讨论,然后出现了这个问题。标准允许我们int通过char左值更改类型的对象。

int a;
char *b = (char*) &a;
*b = 0;

如果我们知道对齐没问题,我们是否可以在相反的方向这样做?

我看到的问题是,如果将别名规则视为非对称关系,则别名规则不涵盖以下简单情况

int a;
a = 0;

原因是,每个对象都包含一系列sizeof(obj) unsigned char对象(称为“对象表示”)。如果我们更改int,我们将更改部分或全部这些对象。然而,别名规则只规定我们可以intcharor改变 a unsigned char,但不能反过来。另一个例子

int a[1];
int *ra = a;
*ra = 0;

3.10/15 只描述了一个方向(“包含...的聚合或联合类型”),但这次我们需要另一种方式(“作为元素或非静态数据成员类型的类型总计的...”)。

是否暗示了另一个方向?这个问题也适用于 C。

4

3 回答 3

2

别名规则只是声明内存中的任何给定对象都有一个“有效类型”(C99 6.5.7,加上脚注 73),并且对此类对象的任何访问都通过以下方式之一进行:

  • 与有效类型兼容的类型(限定符如constandrestrict以及有符号/无符号可能会有所不同)
  • 包含一种此类类型的结构或联合
  • 字符类型

当然,有效类型没有在高级中指定 - 它只是一个用于指定别名的构造。但目的只是您不要使用两种不同的非字符类型访问同一个对象。

所以答案是,是的,你确实可以走另一个方向。

于 2011-01-21T13:28:57.023 回答
1

标准(C99 6.3.2.3 §7)将这样的指针转换定义为“很好”,转换后的指针将指向相同的地址。(除非 CPU 具有使强制转换不可能的对齐方式,否则它是未定义的行为。)

也就是说,实际演员阵容本身就很好。如果您开始操纵数据会发生什么……现在这是另一个由实现定义的故事。

以下是标准:

“指向对象或不完整类型的指针可能会转换为指向不同对象或不完整类型的指针。如果结果指针未正确对齐 (57) 指向的类型,则行为未定义。否则,转换时再次返回,结果将等于原始指针。

当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。结果的连续增量,直到对象的大小,产生指向对象剩余字节的指针。”

"57) 一般来说,“正确对齐”的概念是可传递的:如果指向类型 A 的指针与指向类型 B 的指针正确对齐,而指向类型 B 的指针又正确对齐指向类型 C 的指针,则指向对于指向 C 类型的指针,类型 A 正确对齐。”

于 2011-01-21T14:37:04.547 回答
0

我想我对这个问题有点困惑,但是第二个和第三个示例是通过具有对象类型的左值访问 int (int在示例中)。

C++ 3.10/15 作为第一项声明,可以通过具有“对象的动态类型”类型的左值访问对象。

我对这个问题有什么误解?

于 2011-01-21T21:41:57.337 回答