拿这段代码:
int main()
{
short a = 2, b = 1;
float f = 5.36f;
-a * f;
b * f;
}
编译:
~ $ g++ -std=c++11 wconversion.cpp -Wconversion
wconversion.cpp: In function ‘int main()’:
wconversion.cpp:6:8: warning: conversion to ‘float’ from ‘int’ may alter its value [-Wconversion]
-a * f;
为什么警告a
,而不是b
?
编辑:因为它似乎取决于编译器版本:我正在使用GCC 4.9。此外,a
和b
不一致的其他代码中的行为也是相同的。
答案 0 :(得分:4)
32位类型int
的某些值无法完全表示为float
。如果将int
这样的值转换为float
,则会选择最接近的float
(两个周围浮点数之间的选择是实现定义的,但几乎所有实现都选择最近的一个)
警告似乎与从int
或更宽的整数类型转换为float
期间的信息丢失有关。
b
?智能编译器不需要发出b
的警告,因为b
是short
(可能是OP架构上的16位) ,b
在运行时可能具有的所有值都可以完全表示为float
。
-a
?智能编译器可以出于同样的原因避免对a
发出警告。由于促销,-a
的类型为int
,但-a
的值范围为 - (2 15 -1)至2 15 (在OP的平台上)。所有这些值都可以完全表示为float。但是,此处似乎触发的一般警告是针对类型int
或更宽的表达式。海湾合作委员会似乎无法发现消息警告的情况不会出现。
答案 1 :(得分:0)
这取决于gcc的版本。在4.4.5中,我在两行都收到警告:
foo.c:2: warning: function declaration isn’t a prototype
foo.c: In function ‘main’:
foo.c:6: warning: conversion to ‘float’ from ‘int’ may alter its value
foo.c:6: warning: statement with no effect
foo.c:7: warning: conversion to ‘float’ from ‘int’ may alter its value
foo.c:7: warning: statement with no effect
foo.c:8: warning: control reaches end of non-void function
也许开发人员提出了一个特例,认识到b
是“1”并且存在精确转换,而“-2”在用户方面可能存在歧义(特殊情况除外)转换将四舍五入 - 启发式可能需要细化)。使用gcc 4.9,我只收到一个警告:
foo.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
int main()
^
foo.c: In function ‘main’:
foo.c:6:6: warning: conversion to ‘float’ from ‘int’ may alter its value [-Wconversion]
-a * f;
^
foo.c:6:3: warning: statement with no effect [-Wunused-value]
-a * f;
^
foo.c:7:3: warning: statement with no effect [-Wunused-value]
b * f;
^
foo.c:8:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
gcc (Debian 4.9.2-10) 4.9.2