【问题标题】:Why I get a "type-punned" warning even when using a `char *`?为什么即使使用 `char *` 我也会收到“类型双关语”警告?
【发布时间】:2017-06-24 09:36:50
【问题描述】:

gcc (6.3.1 20170109) 编译以下程序时

#include <stdio.h>

int main(int argc, const char *argv[]) {
    unsigned char x[] = {0x66, 0x19};
    printf("%i\n", ((short *)((char *)&x[0]))[0]);
    return 0;
}

生成警告:

pun.c:在函数“main”中: pun.c:5:5:警告:取消引用类型双关指针将破坏严格别名规则 [-Wstrict-aliasing]

在使用char 指针时不应该允许类型别名吗?

【问题讨论】:

    标签: gcc strict-aliasing


    【解决方案1】:

    以下是 C11(或至少是免费草案 N1570)对混叠的看法:

    一个对象的存储值只能由具有以下之一的左值表达式访问 以下类型:

    • 与对象的有效类型兼容的类型,
    • 与对象的有效类型兼容的类型的限定版本,
    • 对应于有效类型的有符号或无符号类型 对象,
    • 一种类型,它是有符号或无符号类型,对应于 对象的有效类型,
    • 一种聚合或联合类型,其中包括上述类型之一 成员(递归地包括子聚合或包含联合的成员),或
    • 一种字符类型。

    字符类型异常意味着您可以通过char*unsigned char* 访问任何类型,但这并不意味着您可以通过任何类型访问char*short* 不符合此处为 char* 列出的其他标准,因此这种使用是未定义的行为。

    另外,如果无条件允许,您可以打破对齐要求:

    short x[] = {1, 2};
    char* alias = x;
    printf("%i\n", *(short*)&alias[1]);
    

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多