c - 在不抑制警告的情况下告诉编译器对齐没问题的可移植方法?

标签 c gcc casting clang compiler-warnings

我们运行的测试之一是使用 -Wcast-align 进行编译。当 float 、 double 和整数之间发生不正确的转换时,它特别有用(它有时会导致 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/

相关文章:

c - setuid 不改变 uid

linux - 如何在 Linux 上将 -fPIC 传递给 GCC

c - i = i + j; 和有什么区别?我+=j;用c语言?

java.lang.String 无法转换为 java.io.InputStream

c - 是否有用于 C 编程的 REPL?

c - 为字符串分配内存的节省时间和内存的方法

c - gcc 链接器如何在包含文件中工作

spring - 代理无法转换为 CLASS

c - 使用 (void *) 作为通用数据容器时的左值问题

c - 整数上的无分支条件——很快,但它们能变得更快吗?