C++ 在C+中键入双关语+;通过extern“;";函数使用并集

C++ 在C+中键入双关语+;通过extern“;";函数使用并集,c++,type-punning,C++,Type Punning,将连续字节转换为其他类型对象的普遍问题可以在C中使用联合来解决。在C++中,由于活动成员定义,这是不可能的。 因此,在下面的代码片段中,实际的“双关”是由C函数完成的。我想知道这是否正确?这当然取决于“extern”关键字的含义 #include <cstdint> #include <cstddef> #include <string.h> namespace Util { namespace detail { union Punn

将连续字节转换为其他类型对象的普遍问题可以在C中使用联合来解决。在C++中,由于活动成员定义,这是不可能的。 因此,在下面的代码片段中,实际的“双关”是由C函数完成的。我想知道这是否正确?这当然取决于“extern”关键字的含义

#include <cstdint>
#include <cstddef>
#include <string.h>

namespace Util {
    namespace detail {
        union Punn {
            std::byte small[sizeof(uint32_t)];
            uint32_t  big;
        };
    }
    extern "C" {
    inline uint32_t read(const Util::detail::Punn* u) {
        return u->big;
    }
    }
}

int main() {
    Util::detail::Punn a;
    a.small[0] = std::byte{1};
    a.small[1] = std::byte{2};
    a.small[2] = std::byte{3};
    a.small[3] = std::byte{4};

    auto x = Util::read(&a);

    return x;
}
#包括
#包括
#包括
命名空间Util{
名称空间详细信息{
联合船民{
std::字节小[sizeof(uint32_t)];
uint32_t大;
};
}
外部“C”{
内联uint32_t读取(const Util::detail::Punn*u){
返回u->big;
}
}
}
int main(){
Util::detail::punna;
a、 小[0]=std::字节{1};
a、 小[1]=std::字节{2};
a、 small[2]=std::字节{3};
a、 小[3]=std::字节{4};
auto x=Util::read(&a);
返回x;
}

我知道解决这个问题的两个真正的方法是移位或memcpy()。因此,请仅讨论使用外部“C”函数的上述代码。(旁白:生成的汇编代码在g++上是正确的,但这并不意味着它严格符合要求。)

这不是一个真正的“C函数”,它只是有C链接(即没有名称混乱或其他问题)……但是如果你把它移到你用C编译器编译的TU上,它可能会发出双关语。只是没有任何C++类型。<代码>外“C”< /C>不意味着“编译这个代码为C”。它的意思是“编译此代码以便与C代码链接”。它仍然是C++。如果我把函数“Read()”移到另一个TU,它就不会被内联。我看不出有什么办法可以做到这一点。这不是一个真正的“C函数”,它只是有C链接(也就是说,没有名字弄错或其他什么)…但是如果你把它移到一个你用C编译器编译的TU上,它可能会双关语。只是没有任何C++类型。<代码>外“C”< /C>不意味着“编译这个代码为C”。它的意思是“编译此代码以便与C代码链接”。它仍然是C++。如果我把函数“Read()”移到另一个TU,它就不会被内联。我看不到实现这一目标的方法。