在不抑制警告的情况下告诉编译器对齐可以的便携式方法?

Portable way to tell the compiler that alignment is OK without supressing the warning?

我们 运行 的测试之一是使用 -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); 表示其对齐。

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

这让 Clang 很高兴,但会增加冗余计算(因此,它可能不适用于发布版本):

uint64_t y = *(uint64_t *)((uintptr_t)x & ~7UL);

通过 GCC,您可以使用 __builtin_assume_aligned。引自 GCC Manual:

Built-in Function:

void * __builtin_assume_aligned (const void *exp, size_t align, ...)

This function returns its first argument, and allows the compiler to assume that the returned pointer is at least align bytes aligned. This built-in can have either two or three arguments, if it has three, the third argument should have integer type, and if it is nonzero means misalignment offset. For example:

void *x = __builtin_assume_aligned (arg, 16);

means that the compiler can assume x, set to arg, is at least 16-byte aligned, while:

void *x = __builtin_assume_aligned (arg, 32, 8);

means that the compiler can assume for x, set to arg, that (char *) x - 8 is 32-byte aligned.

还有一个用于英特尔编译器的 patch for LLVM to implement __builtin_assume_aligned, but it has not been merged yet. Similar intrinsic function exists。不确定 Visual Studio。

由于 OP 现有代码库不需要强类型匹配,使用 void* 可以简单地击败大多数类型匹配,这将消除警告。也参考

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