ES.48:避免使用类型转换
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++包含很多场景下消除类型转换的原则和构造,例如
原文链接
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es48-avoid-casts