Linux 类型双关语警告
我想这样做:Linux 类型双关语警告,linux,gcc,strict-aliasing,type-punning,Linux,Gcc,Strict Aliasing,Type Punning,我想这样做: #define EQ4(a_,b_) (*(int*)(a_)==*(int*)(b_)) char *s1 = "food"; char *s2 = "fred"; return EQ4(s1,s2); 但gcc产生了这样的警告:警告:取消引用类型双关指针将破坏严格的别名规则 我不认为我所做的是为了严格的别名而取消引用,因为我没有将取消引用的指针分配给指针变量 我试过: #define EQ4(a_,b_) (*(const int const *)(a_)==*(cons
#define EQ4(a_,b_) (*(int*)(a_)==*(int*)(b_))
char *s1 = "food";
char *s2 = "fred";
return EQ4(s1,s2);
但gcc产生了这样的警告:警告:取消引用类型双关指针将破坏严格的别名规则
我不认为我所做的是为了严格的别名而取消引用,因为我没有将取消引用的指针分配给指针变量
我试过:
#define EQ4(a_,b_) (*(const int const *)(a_)==*(const int const*)(b_))
这没什么区别
redhat linux版本2.6.32-220,gcc版本=4.4.6
有没有办法使用严格的别名警告,但仍然这样做
谢谢
编辑
这些不起作用:
#define EQ4(a_,b_) (*(int*)(char*)(a_)==*(int*)(char*)(b_))
#define EQ4(a_,b_) (*(int*)(void*)(a_)==*(int*)(void*)(b_))
#define EQ4(a_,b_) (*(int* __attribute__((__may_alias__)))(a_)== \
*(int* __attribute__((__may_alias__)))(b_))
这项工作:
typedef union bork { char a[4], int n32 } __attribute__((__may_alias__)) TBork;
#define EQ4(a_,b_) ((TBork*)(a_)->n32==(TBork*)(b_)->n32)
大家对此有何看法?警告是因为字符串不能保证与声明整型变量时对齐。因此,当CPU需要获取整数值时,可能会使其效率降低(因此出现警告) 您可以从整数开始:
int a;
int b;
char* as=(char*)(&a);
char* bs=(char*)(&b);
as[0]='f'; as[1]='o'; ...
bs[0]='f'; bs[1]='r'; ...
return EQ4(a, b);
注:1) 您必须确保不要复制字符串的终止
'\0'
字符,因为在您提供的示例中,这将触及a
(或b
)之外的内存(请参见下一注释)。2) 在您使用的特定平台上,您必须确保您的字符串不大于int的大小,否则您(再次)接触的内存不属于int。在这种情况下,您的代码中是否进行赋值无关紧要。宏将以任何方式生成加载/存储指令,这些指令需要由编译器进行排序 处理严格别名问题的一种方法是使用联合
inline bool my_equal(char *a, char *b) {
union {
char *cPointer;
int *iPointer;
} left_union = { .cPointer = a }, right_union = { .cPointer = b };
return *left_union.iPointer == *right_union.iPointer;
}
另一种方法是使用
restrict
关键字。使用这种方法,您可以保证不存在任何别名,并且编译器可以按照自己认为合适的方式自由地对操作进行排序,而不会产生获得不需要的结果的风险。但是,请记住,这是一种契约编程。如果你错了,或者有人更改了程序,这可能会导致很难找到错误。正确对齐它们,不知道gcc,但icc识别正确对齐的char*
s,不会对所有响应发出警告感谢。因为对齐而发出的警告很有趣。我们正在使用-march=686进行编译。在gcc的早期版本中,我对memcmp技巧进行了基准测试,尽管存在非最佳对齐方式,但它们的速度似乎要快得多。gcc的当前版本似乎有所改进,它可以降低小范围的memcmp。我可能会停止使用这些技巧中的许多,但不是全部,所以我仍然对所有不同的想法感兴趣。“另一个是使用restrict关键字。”请解释