为C API创建C++绑定:基转派static_cast布局相同时是否有UB?
为C API创建C++绑定:以下代码是否存在未定义行为?
typedef struct ABC_Foo { int x_; } ABC_Foo; namespace abc { class Foo : public ABC_Foo { public: int x() const { return x_; } }; static_assert(sizeof(Foo) == sizeof(ABC_Foo)); } #include <cstdio> #include <new> int main() { ABC_Foo cfoo = {42}; // 这是未定义行为吗? abc::Foo const& cppfoo = *std::launder(static_cast<abc::Foo*>(&cfoo)); printf("%d\n", cppfoo.x()); }
我原本认为这是定义良好的行为,因为abc::Foo与ABC_Foo内存布局等价,且我使用了std::launder处理指针,尽管cppfoo从未实际被构造为abc::Foo实例。
编辑补充:有用户提供了解决方案:要将C中初始化的结构体用作内存布局相同的C++类,应使用std::start_lifetime_as<T>(void*)(同时建议使用组合而非继承)。
class Foo { ABC_Foo cfoo_; ...}; static_assert(sizeof(Foo) == sizeof(ABC_Foo)); ... ABC_Foo cfoo = {42}; abc::Foo* cppfoo = std::start_lifetime_as<abc::Foo>(&cfoo); // 现在访问cppfoo是定义良好的,但访问cfoo会违反别名规则。
内容的提问来源于stack exchange,提问作者Jim Carroll
相关产品推荐
相关产品推荐

