我有一个看起来像这样的函数:
template<typename T>
void some_function(T* buffer) {
BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(unsigned int));
unsigned int temporary_buffer;
int result = some_c_api(&temporary_buffer);
if(result == error)
throw some_exception();
// originally *buffer = reinterpret_cast<T&>(temporary_buffer), but this breaks
// strict aliasing
std::copy( reinterpret_cast<char*>(&temporary_buffer),
reinterpret_cast<char*>(&temporary_buffer) + sizeof(T),
reinterpret_cast<char*>(buffer));
}
在这里将两个不相关的缓冲区都转换为 char*
并复制目标缓冲区可以容纳的字节数是否安全?我使用的是非 C++11 编译器 (gcc 4.1.2)。
我在重构一些代码时遇到了这个问题。原始代码没有此警告,因为它以 void*
形式传递缓冲区。我假设这是非法的是否正确?
最佳答案
这段代码看起来像是等待发生的灾难。如果由于某种原因它必须存在,它应该填充静态断言和注释以明确意图。
基本上,只有满足这些条件时它才会工作:
sizeof(T) <= sizeof(unsigned int)
(因为您要从unsigned int
复制到T
)。我看到这已经被断言了,很好。T
是平凡可复制的(根据 C++11std::is_trivially_copyable
特性)。如果您的编译器不支持与此特性等效的 Boost,只需记录要求即可。
只要满足这些就好了。这就是 trivially copyable 的实际含义——它可以逐字节复制。我只是使用 unsigned char
而不是 char
强调它是字节,而不是字符。
关于c++ - 使用 std::copy 来解决严格的别名是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21531042/