2014-10-30 28 views
7

以下代碼是否合法(在C++ 11/14中)?通過其成員的地址激活嵌套聯合是否合法?

bool foo() { 
    union bar { int i; bool b; }; 
    union baz { char c; bar b; }; 
    auto b = baz{'x'}; 
    auto barptr = &b.b; 
    auto boolptr = &barptr->b; 
    new (boolptr) bool{true}; 
    return b.b.b; 
} 

這個例子是愚蠢的,但我與使用嵌套的工會,而不是一個char []塊的變體成員可變參數variant實施玩耍,並允許這將使我在拷貝構造函數吸塵器當前的嘗試。

把它分解成兩個子問題:

  1. boolptr通過訪問barptr法律即使b.b無效成員分配?
  2. boolptr的就地施工是否激活b.bb.b.b

參考標準將不勝感激。

+0

也許部分地在這裏找到答案:http://stackoverflow.com/questions/11373203/accessing-inactive-union-member-undefined – 2014-10-30 16:27:18

+0

有沒有什麼特殊原因,假設表達式'bb'比'*(&(bb))'更合法?因爲否則,很明顯,兩者都是同樣合法的(沒有人會嚴肅地爭辯說'b.b'是_less_合法!) – MSalters 2014-10-30 16:55:43

回答

2

與有關工會和類型雙關這麼多的問題,但目前還不清楚,如果你的程序中定義的行爲,雖然我強烈期望它像預期的那樣在任何理智的實現。我可以說有確信的是,this program

#include <memory> 
#include <new> 

template <typename T> 
inline void destruct(T& t) { t.~T(); } 

template <typename T, typename...Args> 
inline void construct(T& t, Args&&...args) { 
    ::new((void*)std::addressof(t)) T(std::forward<Args>(args)...); 
} 

template <typename T> 
inline void default_construct(T& t) { 
    ::new((void*)std::addressof(t)) T; 
} 

bool foo() { 
    union bar { int i; bool b; }; 
    union baz { char c; bar b; }; 
    auto b = baz{'x'}; 
    destruct(b.c); 
    default_construct(b.b); 
    construct(b.b.b, true); 
    return b.b.b; 
} 

是符合標準的,正好有你的願望,並compiles to exactly the same assembly as the original program in modern compilers的影響。 Original

foo(): 
    movl $1, %eax 
    ret 

Guaranteed-compliant

foo(): 
    movl $1, %eax 
    ret 
+0

有趣,但很無用。沒有那得到完全優化掉節目短缺,只剩下'返回1;' – 2014-10-31 18:20:48

+0

怎麼'Args'模板參數'default_construct'得到推斷?它沒有用於可推論的情況。 – 2014-10-31 18:24:11

+0

@BenVoigt Clang不會抱怨'Args',clang和gcc都可以有同樣的錯誤嗎? – Casey 2014-10-31 20:16:51