C/ c++中的类型强制转换到底是什么?

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

本文关键字:转换 是什么 c++ 类型      更新时间:2023-10-16

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

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

如果我没记错的话,双精度值比整数(4字节)需要更多的空间(是8字节吗?!)两者的内部表征是完全不同的(对两个/尾数的补充)。那么内部发生了什么呢?这里的例子非常简单,但是在C/c++中有很多类型转换。

编译器如何知道(或程序员),如果我可以转换例如FOO到BAR?

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

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

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

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

标准允许哪些类型的强制转换以及不允许哪些类型的强制转换的完整规则可能会变得相当复杂。在这个回答中,我试图忠实地对其中一些规则做一个比较简明的总结。如果您真的对什么是允许的,什么是不允许的感兴趣,我强烈建议您访问标准并阅读有关类型转换的相应部分。

我想提一件经常被忽视的事情:

    强制转换总是创建目标类型的临时对象(尽管如果目标类型是引用,您不会注意到)。

这可能很重要。例如:

#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));
}

那个cast看起来没用。但外表有时会骗人。

编译器知道如何隐式地执行某些类型强制转换——从double到int就是其中之一。它只是去掉了小数点部分。内部表示作为过程的一部分被转换,因此赋值工作正确。

请注意,有些值太大而无法正确转换。我不记得这种情况下的规则是什么;可由编译器自行决定。

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