【问题标题】:g++ How to get warning on ignoring function return valueg ++如何在忽略函数返回值时获得警告
【发布时间】:2011-02-21 16:01:46
【问题描述】:

lint 会产生一些警告,例如:

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

来自 lint manual

534 忽略函数的返回值

'符号'(与位置比较)A 返回值的函数是 只是为了副作用,因为 例如,在单独的陈述中或 逗号的左侧 操作员。尝试:(无效)函数();到 调用一个函数并忽略它的返回 价值。另见 fvr、fvo 和 fdr §5.5“标志选项”中的标志。

我想在编译期间收到此警告(如果存在)。 gcc/g++ 中是否有任何选项可以实现这一点?我打开了-Wall,但显然没有检测到这一点。

【问题讨论】:

    标签: c++ gcc g++ return-value compiler-warnings


    【解决方案1】:

    我解决了这样的问题:

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

    然后用ignore_result(foo())代替(void)foo()

    然后代码用-Wall编译就好了。

    【讨论】:

      【解决方案2】:

      从 C++17 开始,您可以使用 [[nodiscard]] attribute

      例子:

      [[nodiscard]] int bar() {
        return 42;
      }
      

      【讨论】:

      【解决方案3】:

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

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

      失败的例子:

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

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

      【讨论】:

      【解决方案4】:

      感谢WhirlWindpaxdiablo 的回答和评论。这是我尝试将这些部分组合成一个完整的(?)答案。

      -Wunused-result 相关的 gcc 选项。 默认开启。引用gcc warning options page:

      -Wno-unused-result

      如果函数的调用者标有warn_unused_result 属性(请参阅 Variable Attributes) 不使用它的返回值。默认为-Wunused-result

      因此,解决方案是在函数上应用warn_unused_result 属性。

      这是一个完整的例子。文件未使用的结果.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
      

      再次注意,没有必要使用 -Wunused-result,因为它是默认设置。人们可能很想明确提及它以传达意图。虽然这是一个崇高的意图,但在分析情况后,我的选择却是反对。因为,在编译选项中使用-Wunused-result 可能会产生一种错误的安全感/满足感,除非代码库中的所有函数都使用warn_unused_result 限定,否则这是不正确的。

      【讨论】:

      • 如果-Wunused-result 是默认值,为什么编译器(gcc 9.2.1)没有警告我忽略fgets 返回值? fgets 最重要的目的之一是精确地从流中返回一个字节,因此忽略它可能是一件大事。
      • @m4l490n 也许fgets 没有"标记为属性warn_unused_result"(也许应该是)?
      【解决方案5】:

      -Wunused-result 应该为您执行此操作。这不是警告之一 -Wall 开启:

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

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

      【讨论】:

        猜你喜欢
        • 2011-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多