代码之家  ›  专栏  ›  技术社区  ›  rubenvb

VisualC++警告C48,它为什么只在返回语句上触发?

  •  3
  • rubenvb  · 技术社区  · 14 年前

    我刚刚安装了WindowsSDKV7.1(MSVC 10.0),并运行我的代码通过(几乎)完全警告级别(W3,qmake的默认值 CONFIG += warn_on )对警告感到惊讶 C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)

    在下面的代码中, 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 和海湾合作委员会的 -Wall -pedantic ,所以我想知道:)

    小更新 :我了解该警告旨在让您知道您正在假设int->bool转换,但是 1)你为什么还要使用bool(=)= typedef int 大部分)和2) 为什么会 if(2) 不转换 2 不管是真是假,我认为这就是谓词的全部概念,是真还是假。

    3 回复  |  直到 14 年前
        1
  •  5
  •   sbi    14 年前

    这是怎么回事?我甚至不知道为什么警告会首先触发。我认为第一位代码无论如何已经返回了一个bool。

    1. 流具有隐式转换运算符,该运算符返回 void* . (这是 safe bool idiom . 这样做是因为有更少的上下文 空洞* 编译比 bool 因此,隐式转换可能会引发不需要的情况就更少了。)[1]

    2. 溪流 operator>>() 返回对其左操作数(流)的引用。这样就可以将输入操作链接起来: strm >> value1 >> value2 执行为 ((strm >> value1) >> value2) .

    现在,当你说 if( strm >> value ) , strm >> value 执行并返回流。为了把它放到 if 语句,隐式转换为 空洞* 执行,然后检查该指针是否存在 NULL 或者没有。
    这和 if(ptr) , the 如果 语句隐式将其条件转换为 布尔 但编译器不会对此发出警告,因为条件不是 布尔 是如此普遍。

    return ,这是不同的。如果要返回某个类型,通常返回的表达式应该是该类型。风投的警告很烦人,100次中有99次对我来说是多余的。但是剩下的1%(从来不是性能问题,顺便说一句,我认为这是愚蠢的警告)让我很高兴警告存在。

    此警告的解决方法是

    return 0 != <expression>
    

    哪里 <expression> 是您认为应该被视为布尔值的值。

    [1]史特劳斯鲁在某个地方写着 operator bool() 如果您弄乱了运算符,将静默编译: ostrm >> 5; (注意 >> 而不是 << )会编译得很好,但会默默地做错事。(它将布尔值转换为整数,右移5次,然后放弃该值。)

        2
  •  3
  •   David Thornley    14 年前

    两种情况的区别可能是 return 需要生成返回值,而 if 不必生成任何值,只需进行分支即可。警告显然是必须创建一个新的数据对象,因此它是由 返回 但不是 如果 .

        3
  •  0
  •   Shawn D.    14 年前

    如果条件计算为零或非零,则不转换为布尔值。

    也就是说,如果(1)不生成警告,因为1是非零的。 如果(true)不生成警告,因为true的计算结果为非零。

    所以,整数、指针、布尔值都被转换为“零或非零”,而不是布尔值。

    但是,当您试图从布尔返回的函数中返回整数值时,必须假设您想要模拟这种行为。这就是为什么它表示“我假设你想把‘非零转换为真,零转换为假’,然后你得到警告。