c++ - 使用 std::copy 来解决严格的别名是否安全?

标签 c++ reinterpret-cast strict-aliasing type-punning

我有一个看起来像这样的函数:

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++11 std::is_trivially_copyable 特性)。如果您的编译器不支持与此特性等效的 Boost,只需记录要求即可。

只要满足这些就好了。这就是 trivially copyable 的实际含义——它可以逐字节复制。我只是使用 unsigned char而不是 char强调它是字节,而不是字符。

关于c++ - 使用 std::copy 来解决严格的别名是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21531042/

相关文章:

c# - 如何设置一个 C++ 函数以便它可以被 p/invoke 使用?

c++ - 在结构中使用结构数组时在标量初始值设定项周围加括号

c++ - 如何从 char* 中获取二维 int 数组?

C++ 重新解释_cast?

objective-c - 我们如何将 double 或 float 重新解释为 NSUInteger 来创建哈希?

C++ printf WORD*(ToAscii)

c++ - 如何检查迭代器是否形成连续的内存区域?

c - 取消引用 char* 会抑制严格的别名优化吗?

c - 通过展开继承是否违反严格的别名规则?

c++ - 签名/未签名别名规则是否按预期工作?