c - 这是严格的别名违规吗?

标签 c strict-aliasing

struct __packed element {
    char val;
};

void foo(struct element arr[4], uint32_t a) {
    uint32_t* i = (uint32_t*)arr;
    *i = a;
}

int main(void) {
    struct element arr[4] __aligned(4);

    foo(arr, 5);
    ...
}

与标题差不多,这是 C 中的严格别名违规吗?

假设arr的存储类型是struct element[4]

最佳答案

是的,这 (*i = a) 是一个严格的别名冲突。

N1570 §6.5 p7:

An object shall have its stored value accessed only by an lvalue expression that has one of the following types: 88)

  • a type compatible with the effective type of the object,
  • a qualified version of a type compatible with the effective type of the object,
  • a type that is the signed or unsigned type corresponding to the effective type of the object,
  • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
  • a character type.

以上要求都不满足:

  • uint32_t 与有效类型 char 不兼容。

  • 没有使用限定类型的char

  • uint32_t 不是 char 的无符号版本。

  • struct element 没有 uint32_t 成员。

  • uint32_t 不是字符类型。

如果原始数组的有效类型为 uint32_t 或使用 malloc 分配,有效类型发生在赋值时,这将是合法的。

uint32_t arr;
foo((struct element*)&arr, 5); // Possible pointer conversion issues still apply

void * arr = malloc(4);
foo(arr, 5);

注意 uint32_t* i = (uint32_t*)arr 也可能导致未定义的行为,如果转换后的地址不能存储在 uint32_t* 类型变量。但这是特定于实现的,因此取决于您的平台。

关于c - 这是严格的别名违规吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46886870/

相关文章:

C:数组元素消失

c++ - char* 与先前指令中设置的值的比较未优化?

c++ - 不同的普通可复制类型之间的 std::memcpy 是未定义的行为吗?

c++ - 为什么编译器不再使用严格的别名来优化此UB

指向 struct 的指针可以别名为 unsigned char 数组吗?

c - 将字符串传递给 C 中的函数 - 带或不带指针?

c - 如何将 "trash out"换行符?

c - 识别使用 malloc() 分配的缓冲区

c++ - 为什么 GCC 说 main 的多重定义?我有一个主要的

c++ - G++:可以将 __attribute__((__may_alias__)) 用于指向类实例而不是类定义本身的指针吗?