Tag: 严格别名

gcc,严格的别名和恐怖故事

在gcc-strict-aliasing-and-casting-through-a-union中,我询问是否有任何人遇到指向工会的问题。 到目前为止,答案似乎是没有 。 这个问题更广泛:你有没有关于gcc和严格别名的恐怖故事? 背景: 在c99-strict-aliasing-rules-in-c-gcc中引用AndreyT的答案 : “严格的锯齿规则植根于标准化时代以来存在于C和C ++中的标准的一部分,C89 / 90(6.3)中存在禁止通过另一种types的左值访问一种types的对象的子句。 )以及C ++ 98(3.10 / 15)……只是并非所有的编译器都想要(或敢于)执行或依赖它。 那么, gcc现在正在用它的-fstrict-aliasing开关来这么做。 这导致了一些问题。 例如,请参阅有关Mysql bug的优秀文章http://davmac.wordpress.com/2009/10/以及http://cellperformance.beyond3d.com/articles/2006/06/understanding中的同样出色的讨论-strict-aliasing.html 。 其他一些不太相关的链接: 业绩冲击的-FNO严格走样 严格走样 当-是炭安全换严格指针走样 如何对检测严格走样,在编译时 所以要重复一遍,你有自己的恐怖故事吗? 没有用“ -Wstrict-aliasing表示的问题当然是优选的。 而其他的C编译器也是受欢迎的。 6月2日新增 :迈克尔·伯尔(Michael Burr)的答案中的第一个链接确实是一个恐怖故事,或许有点过时(从2003年开始)。 我做了一个快速testing,但问题显然已经消失。 资源: #include <string.h> struct iw_event { /* dummy! */ int len; }; char *iwe_stream_add_event( char *stream, /* Stream of events […]

解引用types的指针会破坏严格的别名规则

我使用下面的一段代码作为更大程序的一部分从文件中读取数据。 double data_read(FILE *stream,int code) { char data[8]; switch(code) { case 0x08: return (unsigned char)fgetc(stream); case 0x09: return (signed char)fgetc(stream); case 0x0b: data[1] = fgetc(stream); data[0] = fgetc(stream); return *(short*)data; case 0x0c: for(int i=3;i>=0;i–) data[i] = fgetc(stream); return *(int*)data; case 0x0d: for(int i=3;i>=0;i–) data[i] = fgetc(stream); return *(float*)data; case 0x0e: for(int i=7;i>=0;i–) data[i] = fgetc(stream); […]

在C中违反严格别名,即使没有任何铸造?

*i和ui如何在这个代码中打印不同的数字,即使i被定义为int *i = &u.i; ? 我只能假设我在这里触发了UB,但我看不出如何。 (如果我select'C'作为语言, ideone demo会复制,但@ 2501指出,不是'C99 strict'是语言,但是我再次遇到gcc-5.3.0 -std=c99 ! ) // gcc -fstrict-aliasing -std=c99 -O2 union { int i; short s; } u; int * i = &u.i; short * s = &u.s; int main() { *i = 2; *s = 100; printf(" *i = %d\n", *i); // prints 2 printf("ui […]

“解引用types指针会打破严格别名规则”警告

我使用一个代码,我把一个枚举*到int *。 像这样的东西: enum foo { … } … foo foobar; int *pi = reinterpret_cast<int*>(&foobar); 编译代码时(g ++ 4.1.2),我得到以下警告信息: dereferencing type-punned pointer will break strict-aliasing rules 我search了这个消息,发现只有在严格的别名优化的时候才会发生。 我有以下问题: 如果我留下这个警告的代码,它会产生潜在的错误的代码? 有什么办法解决这个问题? 如果没有,是否可以从源文件中closures严格的别名(因为我不想closures所有的源文件,我不想为这个源文件做一个单独的Makefile规则)? 是的,我实际上需要这种别名。

海湾合作委员会,严格的别名,并通过工会铸造

你有什么恐怖的故事要讲? GCC手册最近增加了一个关于“严格别名”和通过工会投射指针的警告: […]考虑地址,转换结果指针和解引用结果具有未定义的行为 [强调添加],即使转换使用联合types,例如: union a_union { int i; double d; }; int f() { double d = 3.0; return ((union a_union *)&d)->i; } 有没有人有一个例子来说明这个未定义的行为? 注意这个问题不是关于什么C99标准说或不说。 这是关于今天gcc和其他现有编译器的实际function。 我只是猜测,但是一个潜在的问题可能在于将d设置为3.0。 因为d是一个永远不会被直接读取的临时variables,并且永远不会通过“有点兼容的”指针读取,所以编译器可能不费心去设置它。 然后f()会从栈中返回一些垃圾。 我简单,天真,尝试失败。 例如: #include <stdio.h> union a_union { int i; double d; }; int f1(void) { union a_union t; td = 3333333.0; return ti; // gcc […]

严格的别名规则和'char *'指针

什么是严格的锯齿规则被接受的答案? 提到你可以使用char *来别名,而不是别的方式。 对我来说没有任何意义 – 如果我们有两个指针,一个是char *types,另一个是struct something *指向同一个位置,那么第二个别名可能是第二个别名,而第二个别名首先?

为什么优化杀死这个function?

我们最近在大学做了关于几种语言的编程特辑的讲座。 讲师写下了以下function: inline u64 Swap_64(u64 x) { u64 tmp; (*(u32*)&tmp) = Swap_32(*(((u32*)&x)+1)); (*(((u32*)&tmp)+1)) = Swap_32(*(u32*) &x); return tmp; } 虽然我完全理解这在可读性方面也是非常糟糕的风格,但他的主要观点是这部分代码在生产代码中工作良好,直到他们启用了高优化级别。 那么,代码就什么都不做。 他说,编译器会优化variablestmp所有赋值。 但为什么会发生? 我明白,在某些情况下,variables需要被声明为volatile,这样编译器即使认为它们从来没有读过或写过,也不会碰到它们,但我不知道为什么会在这里发生。

什么是严格的锯齿规则?

在询问C语言中常见的不确定行为时 ,比起我提到严格的别名规则,灵魂更加开明。 他们在说什么?