предупреждение: приведение от 'char *' к 'float *' увеличивает требуемое выравнивание с 1 до 4 [-Wcast-align] - PullRequest
0 голосов
/ 22 мая 2019

Есть ли способ использовать ключевое слово c ++ 11 alignas для украшения функции get().При определенных условиях я знаю, что буфер, возвращаемый get(), будет содержать правильно выровненный буфер с плавающей запятой.

Код:

$ cat c.cxx
extern char* get();

void foo()
{
  float *f = (float*)get();
}

приводит к

$ clang++-8 -Wcast-align -c c.cxx
c.cxx:5:14: warning: cast from 'char *' to 'float *' increases required alignment from 1 to 4 [-Wcast-align]
  float *f = (float*)get();
             ^~~~~~~~~~~~~
1 warning generated.

Дляссылаться на функцию char* get(), просто вернуть &v[0] из std::vector<char>, который в зависимости от внутреннего типа может содержать байтовый буфер или буфер с плавающей запятой (вариант).

Ответы [ 3 ]

3 голосов
/ 22 мая 2019

Я бы рекомендовал не использовать приведение в стиле C и отдавать предпочтение reinterpret_cast. Это также имеет приятное свойство избавления от предупреждения.

Однако для правильного ответа на ваш вопрос:

Начиная с C ++ 20 вы можете использовать std::assume_aligned примерно так:

extern char* get();

void foo()
{
  float *f = (float*)std::assume_aligned<alignof(float)>(get());
}

До C ++ 20 вы также можете использовать непереносимые встроенные функции компилятора:

extern char* get();

void foo()
{
  float *f = (float*)__builtin_assume_aligned(get(), alignof(float));
}
1 голос
/ 22 мая 2019

Предупреждения - это просто сообщения от компилятора, предупреждающие программиста (вас) о том, что что-то подозрительно.В общем случае преобразование из char * в float * может вызвать проблемы с выравниванием, отсюда и предупреждение.

Если вы знаете, что в вашем случае использования проблемы с выравниванием не возникнет, и строгий псевдоним будеттоже не проблема, тогда вы можете спокойно проигнорировать предупреждение.Не забудьте оставить комментарий в коде для будущих сопровождающих, чтобы не беспокоиться об этом предупреждении в этом месте.

После прочтения последней строки вашего вопроса я бы не стал полагаться на использование буфера данных vector<char> для этого использования.По крайней мере, вы должны использовать vector<float>: по определению он может содержать числа с плавающей точкой, и всегда безопасно получить доступ к любому типу (здесь массив или числа с плавающей точкой) как массив символов.

1 голос
/ 22 мая 2019

При каких условиях?Если он всегда возвращает буфер с плавающей запятой, сделайте так (float* get()), если иногда это не так, статический декоратор не поможет.

Если вы знаете, что возвращаемый указатель указывает на объект с плавающей запятой, reinterpret_cast может быть использован.Если это не так, но вы все еще хотите использовать число с плавающей запятой, можно использовать memcpy или bit_cast (C ++ 20).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...