我最近遇到了严格的别名规则,但我很难理解如何使用 void *
在不违反规则的情况下执行类型双关。
我知道这违反了规定:
int x = 0xDEADBEEF;
short *y = (short *)&x;
*y = 42;
int z = x;
我知道我可以安全地使用C99中的联合进行打字双关语:
union{
int x;
short y;
} data;
data.x = 0xDEADBEEF;
data.y = 42;
int z = data.x;
但是,我如何使用 void *
在 C99 中安全地执行类型双关语?以下是否正确:
int x = 0xDEADBEEF;
void * helper = (void *)&x;
short *y = (short *)helper;
*y = 42;
int z = x;
我怀疑代码仍然会违反严格的别名规则,因为变量< code>x地址处的内存可以被< code>x和一个解引用的< code>y修改。
如果通过< code>void *没有定义类型双关,那么C99中的< code>void *的目的是什么?
void *
与类型双关无关。其主要目的是:
>
允许泛型分配和释放不关心调用者存储在那里的对象类型的操作(例如malloc
和free
)。
允许调用者通过一个函数传递一个指向任意类型的指针,该函数将通过一个回调把它传递回来,(例如< code>qsort和< code>pthread_create)。在这种情况下,编译器不能强制类型检查;编写调用者和回调函数时,您有责任确保回调函数以正确的类型访问对象。
指向void
的指针也用于一些地方(如memcpy
>),这些地方实际上作为对象的覆盖
char类型可以对任何内容进行别名以访问其表示。在这种情况下,
unsigned char*
也可以工作,但
void*
具有指针自动转换为
在您的示例中,由于原始类型是< code>int而不是union,因此没有合法的方法来进行类型转换并将其作为< code>short进行访问。相反,您可以将< code>x的值复制到一个联合中,在那里执行定义良好的类型双关,然后将其复制回来。一个好的编译器应该完全省略副本。或者,您可以将写操作分解为< code>char写操作,然后这将是合法的别名。
在这些注释中,user @Deduplicator坚持认为,如果别名指针或别名指针是指向字符的指针类型(限定或非限定,有符号或无符号< code>char *),则严格的别名规则允许通过不兼容的类型进行访问。所以,他的观点基本上是 和 符合并具有定义的行为。 然而,在我看来,只有第一种形式是有效的,即当别名指针是指向char的指针时;然而,在另一个方向上却不能,即当别名指针指向不兼容的类型(而不是
下面的getValue()成员函数是否违反了c严格别名规则? 根据该标准,我认为setValue()违反了严格的混淆现象,因为Double既不是聚合类型,也不是IEEE754_64的基类。 getValue()呢?当数据成员采用位字段形式时,它是否是一种未定义的行为,如下例所示? 我正在一个大型项目中使用类似的代码。GCC-O2和-O3输出错误值。如果我添加-fno严格的别名,问题就不存在了。此外
这是一个典型的严格混叠违规示例: 但假设我们添加第二: 这段代码正确吗(不调用未定义的行为)? 标准[expr.reinterpret.cast]如下: 注意:将“指针到<code>T1</code>”类型的prvalue转换为“指针到 和<code>T2是对象类型,并且<code>T2的对齐要求不比<code>T 1 我们使用 类型的原始指针值来访问 类型。 当优化打开时,GCC和Clang都会
对于评估,我希望使用DexGuard加密APK文件中的所有字符串,但不使用模糊、收缩或优化选项 这是可能的还是我被迫混淆APK来加密它 我使用以下命令行加密所有类: conf.pro如下所示: 我已经使用了工具获取所有类名,然后使用
我不知道为什么下面的代码运行得很好,没有< code>gcc错误(< code >-f strict-aliasing-Wstrict-aliasing = 1 )。 如果我遵循严格的别名规则: n1570,§6.5表达式 对象的存储值只能由具有以下类型之一的左值表达式访问: -与对象的有效类型兼容的类型, — 与对象的有效类型兼容的类型的限定版本, -与对象的有效类型对应的有符号或无符号类型的类
我最近通过从源代码编译在CentOS机器上安装了Python 2.7.3。Python 2.7.3安装在/opt/python2.7上,当我安装它时,我只需更改/usr/bin/Python以指向新版本。这显然是错误的,因为当我这样做的时候,它打破了百胜。我会得到以下内容。 我更改了/usr/bin/python以指向python 2.6.6,但现在2.6.6是python的默认版本。你知道怎么解