在gcc-strict-aliasing-and-casting-of-of-union中,我问是否有人遇到过通过指针进行联合修剪的问题。到目前为止,答案似乎是否定的。
这个问题是广泛的:你有任何关于gcc和严格走样恐怖故事?
背景:引用c99-strict-aliasing-rules-in-c-gcc中AndreyT的答案:
“严格的别名规则植根于自[标准化]时代以来C和C ++中存在的标准部分。C89/ 90(6.3中存在禁止通过一种类型的左值访问一种类型的对象的子句。 )以及C ++ 98(3.10 / 15)。...并非所有编译器都希望(或胆敢)强制执行或依赖它。”
好吧,海湾合作委员会现在敢于这样做,它的-fstrict-aliasing开关。这就造成了一些问题。参见,例如,关于Mysql错误的出色文章 http://davmac.wordpress.com/2009/10/,以及在http://cellperformance.beyond3d.com/articles/2006/06/understanding上同样出色的讨论-strict-aliasing.html。
其他一些不相关的链接:
Fno严格混叠的性能影响
严格混叠
什么时候可以对严格的指针别名进行安全处理
如何在编译时检测严格的混叠
重复一遍,您是否有自己的恐怖故事?当然,没有指出的问题-Wstrict-aliasing将是更可取的。也欢迎其他C编译器。
新增6月2日:在第一个环节迈克尔·伯尔的答案,这也的确是有资格作为一个恐怖故事,也许是(2003年)有点过时。我做了一个快速测试,但是问题显然已经消失了。
资源:
#include <string.h>
struct iw_event { /* dummy! */
int len;
};
char *iwe_stream_add_event(
char *stream, /* Stream of events */
char *ends, /* End of stream */
struct iw_event *iwe, /* Payload */
int event_len) /* Real size of payload */
{
/* Check if it's possible */
if ((stream + event_len) < ends) {
iwe->len = event_len;
memcpy(stream, (char *) iwe, event_len);
stream += event_len;
}
return stream;
}
具体投诉是:
一些用户抱怨说,如果在没有-fno-strict-aliasing的情况下编译[以上]代码,则写入和memcpy的顺序会颠倒(这意味着将假len复制到流中)。
编译后的代码,在CYGWIN wih -O3上使用gcc 4.3.4(如果我输入错了,请更正我-我的汇编器有点生锈!):
_iwe_stream_add_event:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
movl 8(%ebp), %eax # stream --> %eax
movl 20(%ebp), %edx # event_len --> %edx
leal (%eax,%edx), %ebx # sum --> %ebx
cmpl 12(%ebp), %ebx # compare sum with ends
对于迈克尔回答中的第二个链接,
*(unsigned short *)&a = 4;
gcc通常会(总是?)发出警告。但我相信对此(对于gcc)的有效解决方案是使用:
#define CAST(type, x) (((union {typeof(x) src; type dst;}*)&(x))->dst)
// ...
CAST(unsigned short, a) = 4;
我问过在gcc-strict-aliasing-and-casting-a-union中这是否可以,但是到目前为止,没有人不同意。
喵喵时光机
相关分类