【问题标题】:Does the C++17 standard guarantee that the address of a union is the same as the address of its members?C++17 标准是否保证联合的地址与其成员的地址相同?
【发布时间】:2017-05-02 21:24:19
【问题描述】:

我目前正在编写一个池分配器。我的问题归结为以下代码:

template <typename T>
union myUnion {
    T data;
    myUnion<T>* nextUnion;
};

void someFunction(){
    myUnion<T> mu;
    T* t = new (std::addressof(mu.data)) T();
    //some code
    myUnion<T>* mu2 = reinterpret_cast<myUnion<T>*>(t);
}

mu的地址总是和mu2一样吗?

【问题讨论】:

  • 哪个标准?
  • 否则联合的意义何在?
  • @MadPhysicist:几乎所有其他内容。
  • @MadPhysicist 该标准规定“联合......是能够在不同时间包含不同类型对象的类”。这就是他们的观点。
  • 无论标准怎么说,T* t = new (std::addressof(mu.data)) T(); 如果涉及任何重要的构造函数或析构函数,可能不是一个好主意。

标签: c++ c++17 language-lawyer union allocator


【解决方案1】:

是的。

9.2/19(N4659 中为 12.2/24):

如果标准布局类对象有任何非静态数据成员,其地址与其第一个非静态数据成员的地址相同。

如果联合本身是标准布局,则联合的地址与其成员的地址相同。

成员的地址都是一样的,感谢9.5/1(N4659中的12.3/2):

分配每个非静态数据成员,就好像它是 结构。联合对象的所有非静态数据成员都具有相同的地址。

【讨论】:

  • 这不是 C++11/C++14 中的 §9.2/20 吗?
  • @Cameron:C++14 中没有 9.2/20。
  • 我的草稿是 9.2/19。没有实际标准,太贵了。
  • @BoundaryImposition:如果你给我 200 瑞士法郎,我会的。话虽如此,那也没用:N4140的内容与实际标准相同。
  • 可能更相关的是“9.5/1 Unions ...每个非静态数据成员都被分配,就好像它是结构的唯一成员一样。联合对象的所有非静态数据成员都有同一个地址。”看到这个答案:stackoverflow.com/a/33056605/4756299 只需找到说明struct 的第一个元素的地址是什么的参考。
【解决方案2】:

仅仅询问两个对象是否具有相同的地址是不够的。例如,保证数组和它的第一个元素具有相同的地址,but you cannot cast one to the other

幸运的是,union 及其成员都保证为pointer-interconvertible,无论它们中的任何一个是否是标准布局。

【讨论】:

    猜你喜欢
    • 2021-11-28
    • 1970-01-01
    • 2023-03-07
    • 2018-12-19
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多