2017-05-04 103 views
12
int main() 
{ 
    short n1 = 8ll; // no warning 

    // warning C4305: 'initializing': truncation from '__int64' to 'short' 
    // warning C4309: 'initializing': truncation of constant value 
    short n2 = 88888ll; 
} 

我的编译器的Visual Studio 2017C++是否允许将任何整数文字隐式转换为短整型?

根据cppref

的类型整数文字的是其中值 可以适合,从类型列表中的第一类型的取决于哪个数字库 以及使用了哪个整数后缀。

带后缀ll的整数字面值应为long long int;所以short n1 = 8ll应该会触发像short n2 = 88888ll这样的警告。

C++是否允许任何整数文字被隐式转换为short int如果它足够小?

+6

“应该触发警告” - 编译器对于警告非常自由。当标准表示需要诊断时,他们可能会发出警告,但他们也可能在标准保持沉默的情况下给予警告。编译器可以很聪明。它知道它自己的限制,所以它可以给出'88888LL'的警告,而不是'8LL'。 – MSalters

+6

您可以使用大括号来禁用隐式转换,例如'short n2 = {88888LL};'(此功能是在C++ 11中添加的) –

+4

@ M.M:支持的初始化器语法禁止**缩小**转换。隐含的扩展转换仍然发生。 –

回答

21

该标准允许在任何两个整数类型之间进行隐式转换,而不管它们的值如何。

编译器警告与代码合法无关;编译器只是在你的代码可能没有做到你想要的时候提醒你。

在您的具体情况下,n1应为8,n2将具有实现定义的值。这两项任务都是合法的C++,但后者可能不是您想要的。


相关standardese:

的整数类型的prvalue可以被转换成另一种整数类型的prvalue。枚举类型可以转换为整数类型的prvalue。
如果目标类型是无符号的,则结果值是与源 整数相同的最小无符号整数(模2 2 n其中n是用于表示无符号类型的位数)。 [注意:在两个 补码表示中,此转换是概念性的,并且位模式没有变化(如果 不是截断)。 - 结束注释]
如果目标类型是带符号的,如果它可以用目标类型表示(并且位域宽度为 ),则值不变。否则,该值是实现定义的。

4.7 /在N4141

1-3
4

是,整数可以隐式转换。这些是从C++标准草案N4296的规则:

4.7积分转换
的整数类型的prvalue可以被转换成的另一 整数类型prvalue。非范型枚举类型的前值可以是 转换为整数类型的prvalue。
如果目的地类型 是无符号的,所得到的值是至少无符号整数 全等到源整数(模2 Ñ其中n是用于表示无符号类型 比特的数量)。
[注意:在两个 补码表示中,此转换是概念性的,并且存在位模式(如果没有截断)没有变化。 - 结束]
如果目的地类型是有符号的,如果 可以在目的地类型中表示,则值不变;否则,值为 实现定义。
如果目标类型是bool,请参阅4.12。 如果源类型为bool,则将值false转换为零,并且将值true转换为1。
允许作为 积分促销的转换被排除在积分转换集之外。

相关问题