专栏首页C++核心准则原文翻译C++核心准则ES.48:避免使用类型转换

C++核心准则ES.48:避免使用类型转换

ES.48: Avoid casts

ES.48:避免使用类型转换

Reason(原因)

Casts are a well-known source of errors. Make some optimizations unreliable.

类型转换是众所周知的错误来源之一。让某些优化处理无法可靠进行。

Example, bad(反面示例)

double d = 2;
auto p = (long*)&d;
auto q = (long long*)&d;
cout << d << ' ' << *p << ' ' << *q << '\n';

What would you think this fragment prints? The result is at best implementation defined. I got

你认为这段代码会输出什么?最好的结果是依赖编译器实现。我得到的是:

2 0 4611686018427387904

Adding

另外

*q = 666;
cout << d << ' ' << *p << ' ' << *q << '\n';

I got

我得到了

3.29048e-321 666 666

Surprised? I'm just glad I didn't crash the program.

神奇么?程序没崩溃我已经很高兴了。

Note(注意)

Programmers who write casts typically assume that they know what they are doing, or that writing a cast makes the program "easier to read". In fact, they often disable the general rules for using values. Overload resolution and template instantiation usually pick the right function if there is a right function to pick. If there is not, maybe there ought to be, rather than applying a local fix (cast).

写出类型转换代码的程序员通常以为知道自己在做什么,或者类型转换可以让代码更容易理解。实际上,它们经常忽视使用值的一般准则。重载和模板例示通常可以选择正确的函数,只要这个函数存在。如果没有,没准应该准备一个,总会好过使用类型转换解决问题。

Note(注意)

Casts are necessary in a systems programming language. For example, how else would we get the address of a device register into a pointer? However, casts are seriously overused as well as a major source of errors.

类型转换在系统级编程中是必要的。例如,不然我们怎么获得登录到指针中的派生类类型的设备?然而,类型转换已经被严重地过度使用,从而变成了错误的主要来源之一。

Note(注意)

If you feel the need for a lot of casts, there may be a fundamental design problem.

如果你觉得需要大量的类型转换,可能是你的设计存在根本性问题。

Exception(例外)

Casting to (void) is the Standard-sanctioned way to turn off [[nodiscard]] warnings. If you are calling a function with a [[nodiscard]] return and you deliberately want to discard the result, first think hard about whether that is really a good idea (there is usually a good reason the author of the function or of the return type used [[nodiscard]] in the first place), but if you still think it's appropriate and your code reviewer agrees, write (void) to turn off the warning.

转换成(void)是被广泛认可的关闭[[nodiscard]]警告的方法。如果你调用了一个带有[[nodiscard]]返回值的函数,而且你就是希望放弃处理该结果,首先考虑一下这是否是一个好主意(通常函数的作者或者当初使用[[nodiscard]]返回值类型都有很好的理由),但如果考虑之后你还是觉得没问题,而且你代码的评审员这也同意的话,使用(void)关闭该警告。

译者注:

[[nodiscard]]是C++17中引入的新特性,如果调用了返回值声明为[[nodiscard]]的运算而没有处理返回值,C++17鼓励编译器发布警告。

Alternatives(其他选项)

Casts are widely (mis) used. Modern C++ has rules and constructs that eliminate the need for casts in many contexts, such as

类型转换被广泛地使用。现代C++包含很多场景下消除类型转换的原则和构造,例如

  • Use templates
  • 使用模板
  • Use std::variant
  • 使用std::variant
  • Rely on the well-defined, safe, implicit conversions between pointer types
  • 依靠指针类型之间经过良好定义的,安全的,显式类型转换。
Enforcement(实施建议)
  • Force the elimination of C-style casts, except when casting a [[nodiscard]] function return value to void.
  • 强制消除C风格类型转换,除了将[[nodiscard]]函数返回值转换为void之外。
  • Warn if there are many functional style casts (there is an obvious problem in quantifying 'many').
  • 如果存在很多功能性的类型转换(修饰词“很多”显然有问题),发布警告。
  • The type profile bans reinterpret_cast.
  • 类型规则群组禁止使用reinterpret_cast。
  • Warn against identity casts between pointer types, where the source and target types are the same (#Pro-type-identitycast).
  • 如果目的类型和源类型相同,针对指针类型之间的身份转换发布警告。
  • Warn if a pointer cast could be implicit.
  • 如果指针类型转换可能会隐式发生,发布警告。

原文链接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es48-avoid-casts

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

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

原始发表时间:2020-05-15

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++核心准则R.12:立即将显式分配的资源交给资源管理对象​

    If you don't, an exception or a return may lead to a leak.

    面向对象思考
  • C++核心准则T.11:只要可能就使用标准概念

    "Standard" concepts (as provided by the GSL and the Ranges TS, and hopefully soo...

    面向对象思考
  • C++核心准则C.129:设计类层次关系时,区分实现继承和接口继承‍

    C.129: When designing a class hierarchy, distinguish between implementation inhe...

    面向对象思考
  • yum install空间不足

    本地要编一个 ceph-exporter,需要 ceph 的相关库,于是在开发机上 yum install librados2-devel,报错了,因为第一次遇...

    runzhliu
  • 如何关闭SAP ICF调试

    I checked the trace but there is no long running statement on CRMD_ORDER_INDEX.

    Jerry Wang
  • DAY55:阅读 Formatted Output

    Formatted output is only supported by devices of compute capability 2.x and high...

    GPUS Lady
  • 【转载】使用python库--Graphviz为论文画出漂亮的示意图

    DOT is a plain text graph description language. It is a simple way of describing...

    marsggbo
  • XML进阶:Level 1 - XML简介

    Woodson
  • salesforce 零基础开发入门学习(九)Approval Process 介绍

    在阅读此篇文章前,可以先参考阅读一个前辈总结的关于Approval Process的操作。以下为参考的链接: http://www.cnblogs.com/mi...

    用户1169343
  • Rocketmq之No route info of this topic解决思路

    用过rocketmq的人,采用客户端调用的时候,可能会相对高频的出现的 No route info of this topic这个异常问题,然后你可能会拿着这个...

    lyb-geek

扫码关注云+社区

领取腾讯云代金券