天天看点

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​​

继续阅读