C / C ++中的types究竟是什么?

C / C ++中的types究竟是什么? 编译器如何检查是否需要明确的types转换(和有效的)? 它是否比较价值所需的空间? 如果我有例如:

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

如果我没有记错,一个double值需要更多的空间(8个字节?!),而不是一个整数(4个字节)。 而且两者的内在performance是完全不同的(两个/尾数的补充)。 那么内部会发生什么? 这里的例子非常简单,但是在C / C ++中有大量的types转换。

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

types转换基本上是从一种types转换为另一种types。 它可以是隐式的(即由编译器自动完成,也许在进程中丢失信息)或明确的(即由开发人员在代码中指定)。 这些types所占用的空间是次要的。 更重要的是转换的适用性(有时候也很方便)。

隐式转换可能会丢失信息,标志可能丢失/获得,并且可能发生溢出/下溢。 编译器不会保护你免受这些事件的影响,除非编译时产生警告。 当派生types被隐式转换为基本types(按值)时,也可能发生切片。

对于可能非常危险的转换(例如,从基本types到派生types),C ++标准需要显式转换。 不仅如此,它提供了更多限制性的显式types转换,例如static_castdynamic_castreinterpret_castconst_cast ,每一个都将显式const_cast进一步限制为可能转换的一个子集,从而减less了投射错误的可能性。

虽然在C ++中,开发人员有能力通过使用构造函数和重载(转换)运算符来为用户定义的types(包括隐式和显式)扩展转换,但隐式expression式和显式expression式最终都是由C / C ++标准定义的。

标准允许铸造的完整规则,而不是可以相当复杂的规则。 我试图在这个答案中忠实地提出一些这些规则的简要总结。 如果你真的对什么是不允许的,什么是不允许的,我强烈build议你访问标准并阅读相应的types转换部分。

只想提一些经常被忽视的东西:

  • 转换总是创build一个目标types的临时(尽pipe如果目标types是一个引用,你不会注意到)。

这可能很重要。 例如:

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

那个投影看起来毫无用处。 但看起来可能是骗人的 。

有一些types转换,编译器知道如何隐式执行 – double到int就是其中之一。 它只是放下小数部分。 内部表示被转换为过程的一部分,因此分配工作正常。

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

编写一段代码的C程序,并按照如何让GCC生成汇编代码来查看编译器如何进行types转换。