C/C++ 中的类型转换究竟是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7558837/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:07:38  来源:igfitidea点击:

What exactly is a type cast in C/C++?

c++ctypescasting

提问by pluckyDuck

What exactly is a type cast in C/C++? How does the compiler check if an explicit typecast is needed (and valid)? Does it compare the space required for an value? If I have for example:

C/C++ 中的类型转换究竟是什么?编译器如何检查是否需要(并且有效)显式类型转换?它是否比较了一个值所需的空间?如果我有例如:

int a;
double b = 15.0;
a = (int) b;

If I remember correctly a double value requires more space (was it 8 bytes?!) than an integer (4 bytes). And the internal representation of both are completely different (complement on two/mantissa). So what happens internally? The example here is quite straightforward, but in C/C++ there are plentiful typecasts.

如果我没记错的话,double 值需要比整数(4 字节)更多的空间(是 8 字节吗?!)。并且两者的内部表示完全不同(对二/尾数进行补码)。那么内部会发生什么?这里的例子非常简单,但在 C/C++ 中有大量的类型转换。

How does the compiler know (or the programmer) if I can cast e.g. FOO to BAR?

编译器(或程序员)如何知道我是否可以将例如 FOO 转换为 BAR?

采纳答案by Michael Goldshteyn

A type cast is basically a conversion from one type to another. It can be implicit (i.e., done automatically by the compiler, perhaps losing info in the process) or explicit (i.e., specified by the developer in the code). The space occupied by the types is of secondary importance. More important is the applicability (and sometimes convenice) of conversion.

类型转换基本上是从一种类型到另一种类型的转换。它可以是隐式的(即,由编译器自动完成,可能会在过程中丢失信息)或显式的(即,由开发人员在代码中指定)。类型占用的空间是次要的。更重要的是转换的适用性(有时是方便)。

It is possible for implicit conversions to lose information, signs can be lost / gained, and overflow / underflow can occur. The compiler will not protect you from these events, except maybe through a warning that is generated at compile time. Slicing can also occur when a derived type is implicitly converted to a base type (by value).

隐式转换可能会丢失信息,可能会丢失/获得符号,并且可能会发生上溢/下溢。编译器不会保护您免受这些事件的影响,除非通过在编译时生成的警告。当派生类型隐式转换为基类型(按值)时,也可能发生切片。

For conversions that can be downright dangerous (e.g., from a base to a derived type), the C++ standard requires an explicit cast. Not only that, but it offers more restrictive explicit casts, such as static_cast, dynamic_cast, reinterpret_cast, and const_cast, each of which further restricts the explicit cast to only a subset of possible conversions, reducing the potential for casting errors.

对于可能非常危险的转换(例如,从基础类型到派生类型),C++ 标准要求进行显式转换。不仅如此,它还提供了更多限制性的显式转换,例如static_cast, dynamic_cast, reinterpret_cast, 和const_cast,每个都进一步将显式转换限制为仅可能转换的一个子集,从而减少了转换错误的可能性。

Valid conversions, both implicit and explict are ultimately defined by the C/C++ standards, although in C++, the developer has the ability to extend conversions for user defined types, both implicit and explicit, via the use of constructors and overloaded (cast) operators.

隐式和显式的有效转换最终由 C/C++ 标准定义,尽管在 C++ 中,开发人员可以通过使用构造函数和重载(强制转换)运算符扩展用户定义类型的转换,包括隐式和显式.

The complete rules for which casts are allowed by the standards and which are not can get quite intricate. I have tried to faithfully present a somewhat concise summary of some of those rules in this answer. If you are truly interested in what is and is not allowed, I strongly urge you to visit the standards and read the respective sections on type conversion.

标准允许的演员表和不允许的演员表的完整规则可能变得非常复杂。我试图在这个答案中忠实地对其中的一些规则进行一些简明的总结。如果您真的对允许和不允许的内容感兴趣,我强烈建议您访问标准并阅读有关类型转换的相应部分。

回答by Ben Voigt

Just want to mention something frequently overlooked:

只想提一下经常被忽视的事情:

  • A cast always creates a temporary of the target type (although if the target type is a reference, you won't notice).
  • 强制转换总是创建目标类型的临时对象(尽管如果目标类型是引用,您不会注意到)。

This can be important. For example:

这可能很重要。例如:

#include <iostream>

void change_one_print_other( int& a, const int& b )
{
    a = 0;
    std::cout << b << "\n";
}

int main(void)
{
    int x = 5, y = 5;

    change_one_print_other(x, x);
    change_one_print_other(y, static_cast<int>(y));
}

That cast LOOKS useless. But looks can be deceiving.

那个演员看起来没用。但外表是会骗人的

回答by ott--

Make a little C program of your code and follow the instructions in How to get GCC to generate assembly codeto see how the compiler does a type cast.

为您的代码制作一个小 C 程序,并按照如何让 GCC 生成汇编代码中的说明查看编译器如何进行类型转换。

回答by Mark Ransom

There are certain type casts that the compiler knows how to do implicitly - double to int is one of them. It simply drops the decimal part. The internal representation is converted as part of the process so the assignment works correctly.

编译器知道如何隐式执行某些类型转换 - double 到 int 就是其中之一。它只是删除小数部分。内部表示作为过程的一部分进行转换,因此分配工作正常。

Note that there are values too large to be converted properly. I don't remember what the rules are for that case; it may be left at the discretion of the compiler.

请注意,有些值太大而无法正确转换。我不记得那个案子的规则是什么;它可以由编译器自行决定。