首页 文章

为什么即使使用`char *`我也会收到“打字”警告?

提问于
浏览
1

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 指针时不应该键入别名?

1 回答

  • 4

    这是C11(或者至少是免费的N1570草案)关于别名的说法:

    对象的存储值只能由具有以下类型之一的左值表达式访问:与对象的有效类型兼容的类型,与对象的有效类型兼容的类型的限定版本,类型对应于对象的有效类型的有符号或无符号类型,对应于对象有效类型的限定版本的有符号或无符号类型,包含上述类型之一的聚合或联合类型其成员(包括递归地,子聚合或包含联合的成员)或字符类型 .

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

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

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

相关问题