Один из тестов, которые мы запускаем, является компиляцией с -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);
означает, что оно выровнено.
Как передать компилятору, что буфер выровнен без подавления предупреждения?
1) использовать типы stdint.h фиксированной ширины. 2) что не так с 'alignas' от стандарта C? 3) ваш код может вызывать неопределенное поведение. – Olaf
@Olaf - Спасибо. Наша тестовая программа достаточно полная. Мы требуем, чтобы код проходил через ворота безопасности от Clang и GCC Undefined Behavior Sanitizer, которые явно проверяют неприглаженный доступ. Мы также требуем, чтобы он прошел Valgrind, Coverity и Microsoft Enterprise Analysis. Кроме того, утверждение явно проверяет условие и не срабатывает. Поэтому я не считаю, что он страдает UB в этой конкретной области (и я надеюсь, что в каких-либо областях). – jww
Ст. как это может сделать: word64 * ptr = (word64 *) ((intptr_t) buff); Но, возможно, слишком хаки? ;) – Ctx