我是否可以使用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>
取决于内部类型可能包含字节缓冲区或浮点缓冲区(变量)。
答案 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
。如果不是,但仍然需要浮点数,则可以使用memcpy或bit_cast(C ++ 20)。
答案 2 :(得分:1)
警告只是来自编译器的消息,用于警告程序员(您)有可疑之处。在一般情况下,从char *
转换为float *
可能会导致对齐问题,从而引起警告。
如果您知道用例中不会出现对齐问题,并且严格的别名也不是问题,那么您可以放心地忽略该警告。请确保在代码中留下注释,以供将来的维护人员不要在那个地方担心该警告。
在再次阅读了问题的最后一行之后,我不再依赖于使用vector<char>
的数据缓冲区了。至少您应该使用vector<float>
:根据定义,它可以包含浮点数,并且始终可以安全地将任何类型(此处为数组或浮点数)作为char数组访问。