【问题标题】:GCC error: function might be candidate for attribute ‘pure’ if it is known to return normallyGCC 错误:如果已知函数正常返回,则该函数可能是属性“纯”的候选者
【发布时间】:2017-01-18 06:21:08
【问题描述】:

鉴于此代码:

#include <cstdlib>

void func(int x)
{
  if (x)
    abort();
};

g++ -Werror=suggest-attribute=pure 抱怨:

错误:如果已知函数正常返回,则该函数可能是属性“纯”的候选对象

这对我来说似乎很奇怪——不是很明显该函数不知道正常返回吗?有什么方法可以告诉 GCC 它并不总是正常返回,或者我不希望此特定功能出现此警告?

演示:https://godbolt.org/g/720VOT

【问题讨论】:

  • 该函数没有任何效果,但返回的值(对自身来说没有效果)并且该值(仅)取决于参数。这似乎是一个不错的候选人。为什么不呢?
  • @skypjack:该函数确实有副作用——它可以调用abort() 从而结束程序。我认为这意味着它不是“纯”优化的候选者。你不这么认为吗?
  • 哦,你希望编译器知道那是abort。好吧,假设您使用一个指向您分配给abort 的函数的指针,您的期望会相同吗?我认为它不会检查函数,它只是将其作为 void(void) 函数类型接受,以调用不影响返回值的函数类型。因此后者仅取决于参数,函数为pure
  • @skypjack:我认为它不会检查函数,它只是将其作为void(void) 函数类型接受,以不影响返回值。 并非如此,abort 被标记为noreturn,其目的正是影响此类分析 - 例如,this 触发“控制到达非无效函数的结尾”,取消注释最后的 @ 987654335@调用makes the warning go away,并且有一个函数总是调用abortmakes it suggested for noreturn as well
  • @MatteoItalia 有道理,只是有些想法可能是错误的。

标签: c++ gcc compiler-warnings pure-function


【解决方案1】:

这似乎是 gcc 中的一个错误(或者至少是文档和实际实现的差异)。 documentation on -Wsuggest-attribute=pure 内容如下:

-Wsuggest-attribute=pure
-Wsuggest-attribute=const
-Wsuggest-attribute=noreturn

警告可能是属性pure 的候选函数, constnoreturn。编译器只对可见的函数发出警告 在其他编译单元或(在pureconst 的情况下)如果它 不能证明函数正常返回。 函数返回 通常如果它不包含无限循环或异常返回 投掷、呼叫abort 或诱捕。此分析需要选项 -fipa-pure-const,默认情况下在 -O 及更高版本中启用。 更高的优化级别可以提高分析的准确性。

然而,实际分析似乎忽略了不返回调用的可能性,尽管它尊重可能的例外情况:

$ cat test-noreturn.cpp 
[[noreturn]] void foo();

void func(int x)
{
    if (x)
        foo();
}

$ g++ -std=c++11 -c -O -Wsuggest-attribute=pure test-noreturn.cpp 
$ cat test-noreturn-nothrow.cpp 
[[noreturn]] void foo() throw();
//                      ^^^^^^^

void func(int x)
{
    if (x)
        foo();
}
$ g++ -std=c++11 -c -O -Wsuggest-attribute=pure test-noreturn-nothrow.cpp 
test-noreturn-nothrow.cpp: In function ‘void func(int)’:
test-noreturn-nothrow.cpp:4:6: warning: function might be candidate for attribute ‘pure’ if it is known to return normally [-Wsuggest-attribute=pure]
 void func(int x)
      ^

【讨论】:

  • 我不会称它为 bug,而是在分析过程中缺乏精确度。这由“如果已知正常返回”表示,这应该告诉我们编译器未能证明函数的某些属性,但仍然发出警告,希望是最好的。 Noreturn 函数非常频繁,所以我建议在GCC BZ 提交 PR。
猜你喜欢
  • 2020-09-23
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
相关资源
最近更新 更多