我们运行的测试之一是使用-Wcast-align进行编译。当在浮点数,双精度数和整数之间发生不正确的转换时,它特别有用(它有时会导致 SIGBUS ,IIRC)。

我们有基本上执行以下操作的代码。实际案例涉及更多,但这是用法的本质:

typedef uint64_t word64;

static const size_t SIZE = ...;
word64 buffer[SIZE] = ...;

和:
DoSomethingWithBuffer(const byte* buff, size_t size)
{
    word64* ptr = (word64*)buff;
    ...
}

缓冲区在8或16字节边界上对齐。我已经使用手动代码检查和运行时断言验证了对齐方式。

问题是GCC和Clang都警告数据未对齐。它执行了将近2000次,因此我可能会丢失实际的发现。例如:
warning: cast from 'const byte *' (aka 'const unsigned char *') to 'word64 *'
(aka 'unsigned long long *') increases required alignment from 1 to 8 [-Wcast-align]
    word64 tmp = *(word64 *)inBlock ^ roundKeys[0];
                  ^~~~~~~~~~~~~~~~~

使用Clang,我可以使用 assert 进行检测,编译器有时会将其作为诊断提示。但这似乎不适用于这种情况。也就是说,Clang不会使 assert(inBlock % 8 == 0); 意味着其对齐的连接。

如何在不抑制警告的情况下向编译器传达缓冲区已对齐?

最佳答案

由于OP现有的代码库不需要强类型匹配,因此使用void*简单地打败大多数类型匹配即可,这会使警告安静下来。另请参考@Ctx

 void DoSomethingWithBuffer(const byte* buff, size_t size) {
   const word64* ptr = (void*) buff;
   ...
 }

关于c - 告诉编译器对齐没问题而不抑制警告的可移植方式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34967728/

10-11 22:09
查看更多