理解扩展和缩小转换C++

understanding widening and narrowing conversions C++

本文关键字:转换 C++ 缩小 扩展      更新时间:2023-10-16

我想更详细地了解C++类型以及扩展和缩小转换(特定于C++03)。我知道你不能把多个问题放在一个问题线程上,但所有这些问题都与同一主题有关。现在我有了C++类型和范围msdn

现在考虑以下示例:

int a = 35000;
short b;
b=a;

在上面的例子中,我知道a是4个字节,b是2个字节。我知道加宽的转换会增加精度,而变窄的转换会降低精度。我认为上面的例子是一个缩小的强制转换(因为有数据丢失),4个字节变成了两个字节。然而,在某些情况下,我感到困惑的是,正在发生的转变是扩大还是缩小?我们是应该查看类型的字节数来确定它是扩大还是缩小转换,还是应该查看范围?我还读到,为了缩小转换范围,需要显式强制转换,但在这种情况下,编译器没有指出任何错误,而是隐式地进行了错误的转换。关于为什么会发生这种情况,有什么建议吗?我正在使用VS2010

缩小不一定仅取决于大小。例如,long longdouble通常都是相同的大小(每个64位)。尽管如此,任一方向的转换都是一种缩小的转换,因为无论哪种方式,信息都可能丢失。有符号整数类型和大小相同的无符号整数类型之间的转换也可能发生同样的情况——任何方向的转换都可能丢失信息(即,导致值与输入不匹配),因此两者都被视为缩小转换范围。

如果你只在同一个。。。类(例如,所有有符号整数或所有浮点),然后您可以使用项的大小来确定转换是否会涉及变窄(理论上可能有时/情况下这是错误的,但对于大多数硬件和编译器提供的类型来说这是真的)。

还要注意,当源是文字时,C++确实为转换添加了一些例外,并且源可以放在目标中而不会丢失信息,即使源类型的某些值可能导致信息丢失。

例如,如果我执行类似float a = 3.5;的操作,文字3.5的类型为double,但由于它是文字,并且可以在不丢失信息的情况下转换为float,因此即使在禁止缩小转换范围的地方(例如,支持的初始化列表)也允许这样做。

对于积分类型,精度始终为1。加宽转换会增加范围,缩小转换会减小范围。

http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx

空头的范围是-32768到32767。你的输入,3500比这个大。最终发生的情况是,这个数字被塞进了较小的字节数中,导致了一个环绕错误(b为负数)。(具体情况与2的补码有关,但就你的水平而言,只需说"你打破了它,它不起作用"就足够了)。

为了避免这种情况,使用-Wnarrowing-Wall的gcc编译器,或使用visualstudio编译器的/Wall编译器(但我实际上不知道/Wall是否会捕捉到它)。