GCC -Wconversion 与否定一起发出警告,但不会发出其他警告

GCC -Wconversion warns in conjunction with negation, but not otherwise

拿这段代码来说:

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。此外,在 ab 不是常量的其他代码中,行为是相同的。

这取决于 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

警告是什么意思?

某些 32 位类型的值 int 不能完全表示为 float。如果这样的 int 值转换为 float,将选择最近的 float(两个周围浮点数之间的选择是实现定义的,但几乎所有实现都选择最近的一个) .

该警告似乎是关于从 int 或更宽的整数类型转换为 float 期间的信息丢失。

智能编译器是否应该针对 b 发出警告?

智能编译器不需要为 b 发出警告,因为 b 是一个 short(在 OP 的架构上大概是 16 位),并且所有b 在 运行 时可能具有的值可以精确表示为 float.

智能编译器是否应该针对 -a 发出警告?

出于同样的原因,聪明的编译器可以避免 a 的警告。 -a 由于促销而具有类型 int,但 -a 的值范围从 -(215-1) 到 215(在 OP 的平台上)。所有这些值都可以精确地表示为浮点数。但是,此处似乎触发的一般警告是针对类型 int 或更宽的表达式。 GCC 似乎无法检测到消息警告的情况不会出现。