Why I get a “type-punned” warning even when using a `char *`?

有些话、适合烂在心里 提交于 2019-12-11 09:28:17

问题


gcc (6.3.1 20170109) when compiling the following program

#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;
}

generates as warning:

pun.c: In function ‘main’: pun.c:5:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

Shouldn't type aliasing allowed when using char pointers?


回答1:


Here’s what C11 (or at least the free draft N1570) has to say about aliasing:

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

  • 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.

The character type exception means you can access any type via a char* or unsigned char*, but it doesn’t mean you can access a char* via any type. short* doesn’t meet the other criteria listed here for char*, so this use is undefined behaviour.

Plus, you could break alignment requirements if that were allowed unconditionally:

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


来源:https://stackoverflow.com/questions/42084824/why-i-get-a-type-punned-warning-even-when-using-a-char

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!