为什么在通过将非const变量赋值给较小类型的变量来截断非const变量时,g ++或clang不会引发警告?

时间:2011-05-12 08:50:33

标签: c++ g++ compiler-warnings clang

当变量 x 在下面的代码片段中声明为常量时,clang 2.9和g ++ 4.1.2都会生成警告。但是当删除 const 时,就像它在代码片段中一样,即使用以下参数执行时,两个编译器也都不会生成警告:“-Wall -Wextra -pedantic - ANSI“

为什么编译器不会推断并报告相同的警告,因为 x 不易变,并且在类型转换之前无法修改?

#include <iostream>

int main(int argc, char **argv)
{
    unsigned int x = 1000;
    const unsigned char c = x;
    const unsigned int x_ = c;
    std::cout << "x=" << x << " x_=" << x_ << std::endl;
    return 0;
}

使用 const unsigned int x = 1000; g ++提供消息“警告:大整数被隐式截断为无符号类型”并且铿锵“警告:隐式转换从'const unsigned int'到'const unsigned char'将值从1000更改为232 [-Wordstant-conversion] “。

有没有办法在不手动检查代码或依赖正确设计的单元测试的情况下自动检测此情况?

3 个答案:

答案 0 :(得分:4)

对于GCC,添加标记-Wconversion,您将收到所需的警告。它不是-Wall的一部分,因为这么多代码只是忽略了这些类型的东西。我总是打开它,因为它发现很难调试缺陷。

答案 1 :(得分:2)

如果它是const,编译器可以看到它的值并警告截断。如果它不是const,它不能,尽管初始化。这样:

const unsigned int x = 1000;
const unsigned char c = x;

相当于:

const unsigned char c = 1000;

答案 2 :(得分:1)

我用-O3 -fdump-tree-vrp运行gcc,我在转储中看到的是:

std::__ostream_insert<char, std::char_traits<char> > (&cout, &"x="[0], 2);
D.20752_20 = std::basic_ostream<char>::_M_insert<long unsigned int> (&cout, 1000);
std::__ostream_insert<char, std::char_traits<char> > (D.20752_20, &" x_="[0], 4);
D.20715_22 = std::basic_ostream<char>::_M_insert<long unsigned int> (D.20752_20, 232);

即。它只是在cout语句中内联常量1000和232!

如果我使用-O0运行它,它不会转储任何东西,尽管-ftree-vrp和-ftree-ccp开关。

似乎gcc在发出警告之前会内联常量...