C 标准:结构和联合说明符:'suitably converted' 的确切定义是什么?

C standard: structure and union specifiers: what is the exact definition of 'suitably converted'?

N2479 C17..C2x 工作草案 — 2020 年 2 月 5 日 ISO/IEC 9899:202x (E)(强调已添加):

6.7.2.1 Structure and union specifiers

17    Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

18    The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.

问题:suitably converted的确切定义是什么?

补充:如果suitably converted没有确切的定义,那么C实现是否应该记录它的理解?例如(C/C++ 预处理器域),Microsoft 将术语 single item(C++,N4713)理解为 single, permanently indivisible preprocessor token(这会导致从 gcc/clang/other 移植代码时出现问题,这有不同的理解),但是,他们似乎没有记录他们对 single item.

的理解

Question: what is the exact definition of suitably converted?

C 标准没有给出“适当转换”的任何“确切定义”。

我将其解释为“指向初始成员类型的指针”或“指向结构类型的指针”类型的任何转换序列,以便转换规范确保最终指针指向适当的地址。 (例如,尚未通过可能不正确对齐的转换。)

Extra: if there is no exact definition of suitably converted, then shall the C implementation document its understanding?

C 标准不要求 C 实现记录其对“适当转换”的理解或解释。

在此上下文中,“适当转换”是指转换为适当的兼容类型。例如:

#include <stdio.h>

struct mystruct {
    double a;
    int b;
};

int main()
{
    struct mystruct s = { 2.5, 4 };
    double *d = (double *)&s;
    printf("%f\n", *d);   // prints 2.500000
    return 0;
}

此处 struct mystruct 的第一个成员的类型为 double。因此,在这种情况下,“适当的转换”意味着 struct mystruct * 可以通过显式转换转换为 double * 并且它将指向 a 成员。

这个词没有特殊含义。

您正在处理从类型 A 到类型 B 的转换。类型 A 是指向结构的指针类型。没有指定类型 B,只是它必须适合用作指向初始成员的指针。因此,它必须是一个指针(所以我们只处理两个指针类型之间的转换)并且它必须遵循严格的别名规则(目标类型可以是指向窄字符类型的指针,std::byte,实际类型第一个成员的类型,或表示兼容的类型,例如仅在符号上有所不同)。

任何导致合适指针的指针转换满足“适当转换”。

这不是一个正式的术语,但从字里行间我们可以看出它用来表示有效的指针转换。并且需要程序员通过强制转换的方式显式执行。

在 C 中,几乎任何对象指针都可以转换为另一个对象指针转换。但是,如果您通过错误的类型取消引用这样的指针,会发生什么情况就完全不同了。大多数情况下,这是定义不明确的行为。

本例中的有效指针转换:

  • 指向与第一个成员的类型兼容的类型的指针。1) 2) 3)
  • 空指针。 1) 2)
  • 指向字符类型的指针。2)
  • 指向另一个结构类型的指针,其中两个结构都是 union 的一部分并共享兼容类型的公共初始成员。4)

可选地,上述任何情况下的指针都可以是类型限定的。除非第一个成员是限定类型,在这种情况下指针需要共享该类型的所有限定符。 1) 3)

1)简单赋值规则6.5.16.1.
2)指针转换规则(6.3.2.3).
3)兼容类型限定符规则(6.7.3).
4)普通初始序列规则(6.5.2.3).

常见的初始序列一是一个奇怪的规则,显然编译器支持很差,但它符合“严格别名”。