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关键字。”请解释