C++ visualc&x2B+;警告C4800,为什么它只在返回语句时触发?
我刚刚安装了Windows SDK v7.1(MSVC 10.0)并运行了(几乎)完全警告级别的代码(W3,默认为qmake的C++ visualc&x2B+;警告C4800,为什么它只在返回语句时触发?,c++,visual-c++,compiler-warnings,C++,Visual C++,Compiler Warnings,我刚刚安装了Windows SDK v7.1(MSVC 10.0)并运行了(几乎)完全警告级别的代码(W3,默认为qmake的CONFIG+=warn\u on),对警告C4800:'type':强制值bool'true'或'false'(性能警告) 在下面的代码中,stream是一个std::istream,token是一个std::string // in some function returning bool return (stream >> token) // trigg
CONFIG+=warn\u on
),对警告C4800:'type':强制值bool'true'或'false'(性能警告)
在下面的代码中,stream
是一个std::istream
,token
是一个std::string
// in some function returning bool
return (stream >> token) // triggers warning c4800:
// '(void *)': forcing value to bool 'true' or 'false' (performance warning)`
// somewhere else
if( stream >> token ) // does not trigger warning c4800
这是怎么回事?我甚至不明白为什么首先会触发警告。我认为第一位代码已经返回了一个bool
我知道这是吹毛求疵,警告根本不应该存在,但它是我代码中介于MSVC的/W3
和gcc的-Wall-pedantic
之间的唯一警告,所以我想知道:)
小更新:我知道这个警告的目的是让你知道你正在假设int->bool转换,但是1)为什么你仍然使用bool(=
typedef int
大部分)和2)为什么如果(2)
不将2
转换为true或false,我认为这就是谓词的全部想法,是真是假。这两种情况之间的区别可能是返回
需要生成返回值,而如果
不需要生成任何值,只需分支即可。警告显然是必须创建一个新的数据对象,因此它由return
触发,而不是由if
触发,如果条件被评估为零或非零,而不是转换为布尔值
i、 e.如果(1)没有生成警告,因为1不是零。
if(true)不会生成警告,因为true的计算结果为非零
因此,整数、指针、布尔值都转换为“零或非零”,而不是布尔值
但是,当您尝试从具有布尔返回的函数返回整数值时,必须假设您想要模拟该行为。这就是为什么它表示“我假设你想将‘非零转换为真,零转换为假’,你会得到警告
这里发生了什么?我甚至不明白为什么会触发警告。我想第一段代码已经返回了bool
void*
(这是的一个版本。之所以这样做,是因为void*
编译的上下文少于bool
,因此隐式转换可能进入不需要的上下文就更少了。)[1]运算符>>()
返回对其左操作数(流)的引用。这样您就可以链接输入操作:strm>>value1>>value2
作为执行((strm>>value1)>>value2)
if(strm>>value)
时,将执行strm>>value
,并返回一个流。为了将其放入if
语句中,将执行到void*
的隐式转换,然后检查该指针是否为NULL
。这与
if(ptr)
没有区别,if
语句隐式地将其条件转换为bool
,但编译器永远不会对此发出警告,因为这种条件不是bool
非常常见
对于返回
,这是不同的。如果你想返回某种类型的表达式,通常你返回的表达式应该是那种类型的。VC的警告很烦人,对我来说100次中有99次是多余的。但是剩下的1%(不是性能问题,顺便说一句;我认为这个警告很愚蠢)让我高兴的是警告就在那里
此警告的解决方法是
return 0 != <expression>
返回0!=
其中,
是您认为应该被视为布尔值的值
[1] ISTR Stroustrup在某个地方写到,如果你把操作符搞糟了,一个
操作符bool()
会自动编译:ostrm>>5;
(注意>
而不是,这是不正确的。§6.4/4规定(除了开关
)一个条件被转换为bool。如果(例如)如果该值为true
@Gman,则执行其语句:标准规定了行为,而不是编译器必须遵循的确切代码。转换为布尔值,然后根据该值进行分支(在许多体系结构中为整数类型),在语义上等同于不在零/非零上转换和分支。脚注5)中注释的§1.9/1中的标准有时称为“仿佛”规则,因为一个实现可以自由地忽略这个国际标准的任何要求,只要结果是符合要求的,就可以从程序的可观察行为来确定。@David:是的,但答案说它们绝对不会被视为布尔值(而是0或非0),这是完全错误的。它们总是被视为布尔值。(只是转换可能是通过false为0,true为非0来完成的。但条件本身是布尔值。)因此基本上编译器会说:“嘿,返回表达式的类型与返回类型不匹配,请确保它显式。"?感谢您的充分解释,但它仍然表明msvc不符合if
的标准,它应该将条件转换为bool
@ruben:警告与合规性无关。if
的条件当然会转换为bool
,但警告并非严格意义上的转换rsion,它是关于转换以生成一个“真实”值(与“临时”值相反)。+1但要挑剔,我相信这是一个void*转换,而不是const void*。请参见27.4.4。@Neil:你说得对,谢谢。