C++ 为什么g++;或者,当通过将非常量变量赋给较小类型的变量来截断该变量时,clang是否会引发警告?

C++ 为什么g++;或者,当通过将非常量变量赋给较小类型的变量来截断该变量时,clang是否会引发警告?,c++,g++,compiler-warnings,clang,C++,G++,Compiler Warnings,Clang,当变量x在下面的代码段中声明为常量时,clang2.9和g++4.1.2都将生成警告。但是,当删除const时,就像代码段中一样,即使使用我所知道的最严格的参数执行,两个编译器都不会生成警告:“-Wall-Wextra-pedantic-ansi” 为什么编译器不推断并报告相同的警告,因为x不是易失性的,并且在类型转换之前不可能被修改 #include <iostream> int main(int argc, char **argv) { unsigned int x =

当变量x在下面的代码段中声明为常量时,clang2.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;
}
#包括
int main(int argc,字符**argv)
{
无符号整数x=1000;
常量无符号字符c=x;
常数无符号整数x_uc;

std::cout如果它是一个常量,编译器可以看到它的值并警告截断。如果它不是常量,尽管进行了初始化,但它不能。这:

const unsigned int x = 1000;
const unsigned char c = x;
相当于:

const unsigned char c = 1000;

我使用-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);
std::uu ostream_insert(&cout,&x=“[0],2”);
D.20752_20=std::basic_ostream::_M_insert(&cout,1000);
标准::uuu ostream_u插入(D.20752_20,&“x=”[0],4);
D.20715_22=std::basic_ostream::_M_insert(D.20752_20232);
i、 它只是在cout语句中插入常数1000和232

如果我用-O0运行它,它不会转储任何内容,尽管有-ftree vrp和-ftree ccp开关


似乎gcc在发出警告之前先将常量内联起来…

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

存在漏洞非常量变量的ue范围传播传递,这应该可以进行推断。当然,我见过GCC在为非常量整数变量发出的代码中使用即时值,这些变量碰巧永远不会更改,所以说GCC“不能”看到值似乎太悲观了。也许这个特定的警告阶段看不到值。太好了,谢谢!为什么它不包括在Wextra中?我认为Wextra是一个包罗万象的东西,不适合在Wall中。我不知道。它应该是-Wextra的一部分(我认为它实际上应该是-Wall的一部分)@David:不幸的是,
-Wextra
远不是一个万能的。好吧,在gcc或clang中都没有激活几乎所有东西的标志。@MatthieuM.clang的
-Weverything
。不过在将来的这个时候你可能已经知道了haha@RyanHaining当前位置是的,当他们在我出生时引入这面旗帜时,真的很酷t允许在黑名单模式而不是白名单模式下工作(白名单模式不允许自动发现新警告)。