专栏首页C++核心准则原文翻译C++核心准则C.183: 不要使用联合体实现双关类型

C++核心准则C.183: 不要使用联合体实现双关类型

C.183: Don't use a union for type punning

C.183: 不要使用联合体实现双关类型

Reason(原因)

It is undefined behavior to read a union member with a different type from the one with which it was written. Such punning is invisible, or at least harder to spot than using a named cast. Type punning using a union is a source of errors.

向联合体的一个类型的成员写入,然后从联合体不同类型的另一个成员读出数据的行为是没有定义的。这样的双关性操作无法发现,或者至少比使用命名转换更难发现。使用联合体实现双关类型是错误的源头。

Example, bad(反面示例)

union Pun {
    int x;
    unsigned char c[sizeof(int)];
};

The idea of Pun is to be able to look at the character representation of an int.

Pun的想法是可以观察整数的字节表现。

void bad(Pun& u)
{
    u.x = 'x';
    cout << u.c[0] << '\n';     // undefined behavior
}

If you wanted to see the bytes of an int, use a (named) cast:

如果你希望看到整数的各个字节,使用(命名)转换:

void if_you_must_pun(int& x)
{
    auto p = reinterpret_cast<unsigned char*>(&x);
    cout << p[0] << '\n';     // OK; better
    // ...
}

Accessing the result of an reinterpret_cast to a different type from the objects declared type is defined behavior (even though reinterpret_cast is discouraged), but at least we can see that something tricky is going on.

使用reinterpret_case将一个对象从它被定义的类转换为不同的类型之后访问其结果是被定义的行为(即使是这样也不推荐使用reinterpret_cast),但是至少我们可以看到某些危险的处理正在进行。

Note(注意)

Unfortunately, unions are commonly used for type punning. We don't consider "sometimes, it works as expected" a strong argument.

C++17 introduced a distinct type std::byte to facilitate operations on raw object representation. Use that type instead of unsigned char or char for these operations.

不幸的是,联合体经常被用于双关类型。我们不认为“有时会按照预期动作”是一个很有力的观点。C++17引入了新类型std::byte以协助表现针对原始对象的操作。在这些操作中应该使用std::byte而不是unsigned char。

Enforcement(注意)

???

原文链接:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c183-dont-use-a-union-for-type-punning


觉得本文有帮助?请分享给更多人。

关注【面向对象思考】轻松学习每一天!

面向对象开发,面向对象思考!

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++核心准则T.40: 使用函数对象向算法传递操作

    Function objects can carry more information through an interface than a "plain" ...

    面向对象思考
  • C++核心准则边译边学-摘要

    This document is a set of guidelines for using C++ well. The aim of this documen...

    面向对象思考
  • C++核心准则C.152:永远不要将派生类数组的指针赋值给基类指针

    Subscripting the resulting base pointer will lead to invalid object access and p...

    面向对象思考
  • 如何启用SAP CRM产品category的alternative id

    By default SAP has already delivered some standard Alternative ID type and you c...

    Jerry Wang
  • Rails应用分页: Will Paginate

    用户2183996
  • DOLO序言

    在taptap和google play上架了 居然有15人安装,比公主号的安利率大多了。 app store方面,苹果吞了我的钱,还不给我开权限,联系不上客服,...

    沙因Sign
  • 学界 | MINIEYE首席科学家吴建鑫解读ICCV入选论文:用于网络压缩的滤波器级别剪枝算法ThiNet

    机器之心报道 作者:高静宜 近日,南京大学计算机科学与技术系教授、MINIEYE 首席科学家吴建鑫所在团队的一篇论文《ThiNet: 一种用于深度神经网络压缩的...

    机器之心
  • 视频流媒体平台EasyNVR调用接口返回401如何解决?

    目前我们的Easy系列的产品能够给用户提供丰富的接口,有对应的接口调用功能,但是部分接口需要调用登录接口成功才可以正常使用其他需要鉴权的接口功能,本次将介绍前端...

    EasyNVR
  • day03.集群部署zookeeper【大数据教程】

    day03.集群部署zookeeper【大数据教程】 一、Nginx/keepalived/lvs的介绍 1. nginx 1.1. nginx简介 Ngin...

    Java帮帮
  • SAP Structured product - component set

    SAP help: http://help.sap.com/saphelp_crm700_ehp01/helpdata/en/46/576c7701a208e7...

    Jerry Wang

扫码关注云+社区

领取腾讯云代金券