C++ 为什么C++;允许从整数到无符号整数的隐式转换?

C++ 为什么C++;允许从整数到无符号整数的隐式转换?,c++,C++,考虑以下代码: void foo(unsigned int x) { } int main() { foo(-5); return 0; } 编译没有问题。这样的错误会导致很多问题,而且很难找到。为什么C++允许这样的转换?< p>简短的答案是因为C最初支持这样的转换,他们不想在C++中破坏现有的软件。 请注意,某些编译器会对此发出警告。例如,g++-Wconversion将对该构造发出警告 在许多情况下,隐式转换是有用的,例如,当计算中使用int时,但最终结果永远不会是负数(从算

考虑以下代码:

void foo(unsigned int x)
{

}

int main()
{
  foo(-5);
  return 0;
}

编译没有问题。这样的错误会导致很多问题,而且很难找到。为什么C++允许这样的转换?

< p>简短的答案是因为C最初支持这样的转换,他们不想在C++中破坏现有的软件。 请注意,某些编译器会对此发出警告。例如,
g++-Wconversion
将对该构造发出警告

在许多情况下,隐式转换是有用的,例如,当计算中使用
int
时,但最终结果永远不会是负数(从算法中知道,并且可以选择断言)

<>编辑:附加的可能解释:记住,原来C是一种比C++更松散的类型语言。如果使用K&R风格的函数声明,编译器将无法检测此类隐式转换,那么为什么还要在语言中限制它呢。例如,您的代码大致如下所示:

int foo(x)
unsigned int x
{

}

int main()
{
  foo(-5);
  return 0;
}
而声明本身就是
intfoo(x)

编译器实际上依靠程序员将正确的类型传递到每个函数调用中,并且在调用站点上没有进行转换。然后,当函数实际被调用时,堆栈(etc)上的数据将按照函数声明指示的方式进行解释

一旦编写了依赖于这种隐式转换的代码,即使在函数原型中添加了实际的类型信息,也很难将其从ANSI C中删除。这可能就是为什么它现在仍然保持在C中。然后C++不断地决定不破坏C的向后兼容性,继续允许这种隐式转换。

UL>
  • 这只是一种语言的另一个怪癖,它有许多愚蠢的怪癖
  • 转换被很好地定义为环绕,这在某些情况下可能很有用
  • 它与C向后兼容,这是因为上面的原因

  • 您可以选择。

    因为该标准允许从
    有符号
    无符号
    类型的隐式转换


    < > >代码>(int)A+(无符号)B<代码>结果为<代码>未签名< /代码> -这是C++标准。

    < P> @ USE16815是正确的。C++最初被设计成C的超集,假装尽可能向后兼容。 “C”理念是将大部分责任交给程序员,而不是拒绝危险的事情。对于C程序员来说,这是天堂,对于Java程序员来说,这是地狱。。。品味问题

    我将挖掘标准,看看它到底写在哪里,但我现在没有时间做这件事。我会尽快修改我的答案

    我也同意一些继承的自由可能会导致很难调试的错误,因此我补充说,在g++中,您可以打开一个警告来防止犯这种错误:
    -Wconversion
    标志

    警告可能改变值的隐式转换。这包括 实数和整数之间的转换, 与abs(x)一样,当x是双的时候; 有符号和有符号之间的转换 unsigned,比如unsigned ui=-1;和 转换为较小的类型,如 sqrtf(M_-PI)。不要发出明确警告 像abs((int)x)和ui这样的强制转换= (无符号)-1,或者如果值不是 通过类似abs的转换进行更改 (2.0). 关于转换的警告 在有符号整数和无符号整数之间 可以通过使用禁用 -Wno符号转换

    对于C++,还警告用户定义的过载解决方法 转换;以及将要进行的转换 切勿使用类型转换运算符: 转换为void,同一类型,a 基类或对它们的引用。 关于之间转换的警告 有符号整数和无符号整数是 在C++中默认为禁用 -Wsign转换已显式启用


    其他编译器可能有类似的标志。

    在最初的C标准出现时,许多(所有?)编译器已经允许这种转换。基于C的基本原理,似乎很少(如果有的话)讨论是否应该允许这种隐式转换。当C++出现时,这种隐式转换非常普遍,消除它们会使语言与大量C代码不兼容。它可能会使C++更干净;这肯定会使它少用很多——以至于它可能永远也不会超越“C带类”阶段,甚至这也只是贝尔实验室历史上一个被忽视的脚注

    这条线上唯一真正的问题是在提升“小于”int的无符号值时,“保留值”和“保留无符号”规则之间的区别。当(例如)向无符号字符添加了一个无符号短字符时,就会出现这两个规则之间的区别

    无符号保留规则表示将两个值提升为无符号整数。值保留规则表示将两个值提升为
    int
    ,前提是它可以表示原始类型的所有值(例如,常见的8位字符、16位短字符和32位整数)。另一方面,如果int和short都是16位,那么int不能表示unsigned short的所有值,那么可以将unsigned short提升为unsigned int(注意,它仍然被视为提升,即使它只发生在实际上不是提升的情况下——即,这两种类型的大小相同)


    不管是好是坏,(这两个方向已经争论了很多次)委员会选择了保留价值而不是保留未签名的促销。但是,注意,这是一个相反的转换:不是从签名到无符号,而是关于是否将未签名转换为签名。

    陈腐的答案:因为C++被设计成(主要)向后兼容C,而C允许在积分之间隐式转换。