警告:从'char *'转换为'float *'将所需的对齐方式从1增加到4 [-Wcast-align]

时间:2019-05-22 12:05:32

标签: c++ c++11

我是否可以使用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]的{​​{1}}即可,该std::vector<char>取决于内部类型可能包含字节缓冲区或浮点缓冲区(变量)。

3 个答案:

答案 0 :(得分:3)

我建议您不要使用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 :(得分:1)

在什么样的条件下?如果它总是返回一个float缓冲区,请设置为{float* get()),如果有时不这样做,则静态装饰器将无济于事。

如果您知道返回的指针指向浮点数,则可以使用reinterpret_cast。如果不是,但仍然需要浮点数,则可以使用memcpybit_cast(C ++ 20)。

答案 2 :(得分:1)

警告只是来自编译器的消息,用于警告程序员(您)有可疑之处。在一般情况下,从char *转换为float *可能会导致对齐问题,从而引起警告。

如果您知道用例中不会出现对齐问题,并且严格的别名也不是问题,那么您可以放心地忽略该警告。请确保在代码中留下注释,以供将来的维护人员不要在那个地方担心该警告。

在再次阅读了问题的最后一行之后,我不再依赖于使用vector<char>的数据缓冲区了。至少您应该使用vector<float>:根据定义,它可以包含浮点数,并且始终可以安全地将任何类型(此处为数组或浮点数)作为char数组访问。