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

g++如何获得忽略函数返回值的警告

  •  25
  • Arun  · 技术社区  · 15 年前

    Lint会发出一些警告,比如:

    foo.c XXX Warning 534: Ignoring return value of function bar()
    

    来自皮毛 manual

    534忽略函数的返回值

    “符号”(与位置比较)a 返回值的函数是 只是为了副作用 例如,在语句中,单独使用或 逗号的左边 操作员。try:(void)function();to 调用函数并忽略其返回 价值。另见fvr、fvo和fdr 第5.5节“标志选项”中的标志。

    我希望在编译期间得到这个警告(如果有)。gcc/g++中是否有实现这一点的选项?我已经打开 -Wall 但这显然没有发现这一点。

    5 回复  |  直到 7 年前
        1
  •  26
  •   Community CDub    8 年前

    多亏了 WhirlWind paxdiablo 回答和评论。我试着把这些碎片拼凑成一个完整的(?)回答。

    -Wunused-result 相关GCC选项。和 默认情况下打开 . 引用 gcc warning options page :

    -Wno-unused-result

    如果调用带有属性标记的函数,则不发出警告 warn_unused_result (见 Variable Attributes )不使用其返回值。默认值为 -未使用的结果

    因此,解决方案是应用 警告未使用的结果 函数的属性。

    下面是一个完整的例子。文件的内容未使用的结果.c

    int foo() { return 3; }
    
    int bar() __attribute__((warn_unused_result));
    int bar() { return 5; }
    
    int main()
    {
        foo();
        bar();    /* line 9 */
        return 0;
    }
    

    以及相应的编制结果:

    $gcc unused_result.c 
    unused_result.c: In function ‘main’:
    unused_result.c:9: warning: ignoring return value of ‘bar’, declared with attribute warn_unused_result
    

    再次注意 没有必要有这样的结果 因为它是默认的。人们可能想明确地提及它来传达意图。虽然这是一个高尚的意图,但在分析了形势之后,我的选择却与之相反。因为,拥有 -未使用的结果 在编译选项中,可能会产生错误的安全感/满足感,除非 全部的 代码库中的函数通过 警告未使用的结果 .

        2
  •  16
  •   Jyaif    8 年前

    因为C++ 17,你可以使用 [[nodiscard]] attribute .

    例子:

    [[nodiscard]] int bar() {
      return 42;
    }
    
        3
  •  6
  •   WhirlWind    15 年前

    -Wunused-result 应该为你做这个。这不是警告之一-墙打开:

    http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

    函数必须应用warn_unused_result属性(感谢paxdiablo)。

        4
  •  4
  •   Jonah    9 年前

    关于使用的答案 __attribute__((warn_unused_result)) 是正确的。不过,gcc不太擅长这个功能!注意:它不会对非POD类型发出警告。这意味着,例如,如果返回带有析构函数的类(或带有析构函数的实例变量的类),则永远不会看到忽略结果的警告。

    相关错误: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66177

    失败示例:

    struct Error {
    ~Error();
    };
    
    __attribute__((warn_unused_result)) Error test();
    
    int main()
    {
        test();
        return 0;
    }
    

    所以,对于不太简单的返回类型,不要依赖于此。

        5
  •  0
  •   Sasha Pachev    7 年前

    我这样解决了这个问题:

    #define ignore_result(x) if (x) {}
    

    那么,而不是 (void)foo() 使用 ignore_result(foo())

    然后代码编译 -Wall 很好。