为什么我会收到“打样"字样?即使使用`char *`也警告? [英] Why I get a "type-punned" warning even when using a `char *`?

查看:71
本文介绍了为什么我会收到“打样"字样?即使使用`char *`也警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

gcc(6.3.1 20170109)

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

产生警告:

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

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

使用char指针时不应键入别名吗?

Shouldn't type aliasing allowed when using char pointers?

推荐答案

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

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.

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

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]);

这篇关于为什么我会收到“打样"字样?即使使用`char *`也警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆