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
指针时,是否不允许输入别名?
答案 0 :(得分:4)
以下是C11(或至少是免费的N1570草案)对别名的评价:
对象的存储值只能由具有其中一个的左值表达式访问 以下类型:
- 与对象的有效类型兼容的类型
- 与对象的有效类型兼容的类型的限定版本,
- 对应于有效类型的有符号或无符号类型的类型 对象,
- 对应于合格版本的有符号或无符号类型的类型 有效的对象类型,
- 聚合或联合类型,其中包含上述类型之一 成员(包括,递归地,子集合或包含的联合的成员),或
- 字符类型。
字符类型异常意味着您可以通过char*
或unsigned char*
访问任何类型,但这并不意味着您可以通过任何类型访问char*
。 short*
不符合char*
此处列出的其他条件,因此此用法是未定义的行为。
另外,如果无条件允许,您可以打破对齐要求:
short x[] = {1, 2};
char* alias = x;
printf("%i\n", *(short*)&alias[1]);