天天看點

C++核心準則C.181:避免使用

C.181: Avoid "naked" unions

C.181:避免使用"暴露的"聯合體

Reason(原因)

A naked union is a union without an associated indicator which member (if any) it holds, so that the programmer has to keep track. Naked unions are a source of type errors.

暴露的聯合體指的是不包含用來表示哪個(如果存在的話)成員有效的标志的聯合體,程式員必須對資料流保持跟蹤。暴露狀态的聯合體是錯誤的源頭之一。

Example, bad(反面示例)

union Value {
    int x;
    double d;
};

Value v;
v.d = 987.654;  // v holds a double      

So far, so good, but we can easily misuse the union:

到目前為止還好,但是我們會很容易地錯誤使用這個聯合體:

cout << v.x << '\n';    // BAD, undefined behavior: v holds a double, but we read it as an int      

Note that the type error happened without any explicit cast. When we tested that program the last value printed was 1683627180 which is the integer value for the bit pattern for 987.654. What we have here is an "invisible" type error that happens to give a result that could easily look innocent.

注意類型錯誤是在沒有任何顯式類型轉換的情況下發生的。但我們測試這段程式的時候,輸出的最後一個值是1863627180,它是987.654的二進制對應的整數值。我們在這裡遇到的是一個"不可見"類型錯誤,它恰巧給出一個很容易被判斷為沒有問題的結果。

And, talking about "invisible", this code produced no output:

另外,談到"不可見",下面的代碼不會産生輸出:

v.x = 123;
cout << v.d << '\n';    // BAD: undefined behavior      

Alternative(可選項)

Wrap a union in a class together with a type field.

将聯合體和一個類型字段封裝為一個類。

The C++17 variant type (found in <variant>) does that for you:

C++17的variant類型(可以在<variant>中找到)可以為你做同樣的事:

variant<int, double> v;
v = 123;        // v holds an int
int x = get<int>(v);
v = 123.456;    // v holds a double
w = get<double>(v);      

Enforcement(實施建議)

???

原文連結:

​​https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c181-avoid-naked-unions​​

繼續閱讀