【问题标题】:Unhelpful (maybe wrong?) gcc error message无用(可能是错的?) gcc 错误消息
【发布时间】:2011-01-23 03:53:32
【问题描述】:

我只花了几个小时调试一个编译器错误,如果编译器的错误消息更有帮助,我可以立即修复它。

我把它简化为一个简单的例子:

template <typename T>
int f(int);

template <typename U>
auto g(U x) -> decltype(f(x));

int main()
{
    g(0);
}

错误是:

test.cpp: In function 'int main()':
test.cpp:9:8: error: no matching function for call to 'g(int)'
test.cpp:9:8: note: candidate is:
test.cpp:5:29: note: template<class U> decltype (f(x)) g(U)

这个错误充其量不是误导,最坏的情况是完全错误吗?在我看来,问题是 not 给定的 g 定义与调用不匹配,而是定义格式错误(因为在 decltype 中的表达式 f(x) 中,它试图在不指定 f 的模板参数的情况下调用 f)。

难道不是更合理的错误消息是这样的:

no matching function for call to 'f(int)' in 'decltype(f(x))'
in instantiation of 'g(U)' with U = int

甚至更好:

failed to deduce template parameter 1 in call to 'f(int)' in 'decltype(f(x))'
in instantiation of 'g(U)' with U = int

我早就料到会这样……

【问题讨论】:

  • 哪个版本的 GCC 在哪个平台上?这是 G++ 扩展还是新到 C++0x 的语法?鉴于使用auto,我认为是后者。
  • @Jonathan:decltype 和后期指定的返回类型对于 C++0x 来说是新的(因此这个问题的 C++0x 标记)。从(至少)4.4 版开始,gcc 就支持它们。我引用的错误是由 gcc 4.6 的实验版本产生的,但 4.4 和 4.5 给出了类似的错误。
  • 在 MacOS X 10.6.6 上编译的 GCC 4.5.2 使用 g++ -std=c++0x -c xx.cpp 编译给出了更简单 - 信息量更少 - 错误:xx.cpp: In function ‘int main()’: 和 xx.cpp:9:8: error: no matching function for call to ‘g(int)’。我认为这意味着您使用的是不同版本的 G++ - 可能是较新的版本。
  • @Jonathan:是的,4.4 和 4.5 只是说“没有匹配功能”,只有 4.6 的实验版本提到了候选者。我的观点是,即便如此,它可能会提供更多信息。
  • 在这个阶段,我唯一的建议是'报告给gcc.gnu.org/bugs.html'。他们对 4.5.2 和 4.6 之间的消息进行了改进;也许他们还可以做得更多。

标签: c++ templates c++11 overload-resolution


【解决方案1】:

您很可能在 C++0x 中遇到了“扩展 SFINAE”规则;由于对f(x) 的调用在g 的返回类型的实例化中不起作用(因为无法为对f 的调用推导出T),g 的返回类型无效,因此默默地从重载集中删除。这是一个特性,尽管它会损害错误消息的质量,因为编译器假定 g 是一个您不打算调用的不相关函数。在这种情况下,g 没有其他重载,因此编译器应该给出更好的消息。

有关扩展 SFINAE 的更多信息,请访问http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html。

【讨论】:

  • “编译器假定 g 是您不打算调用的不相关函数”是什么意思?
  • 我试图解释新 SFINAE 规则背后的原因 - 以防止虚假错误意外遇到不应调用的重载。这种推理不适用于这种情况。新规则使错误消息变得更糟而没有任何好处。
【解决方案2】:

使用 Clang 我得到这个错误

C:\Users\SUPER USER\Desktop>clang++ -cc1 -std=c++0x aa.cpp
aa.cpp:9:5: error: no matching function for call to 'g'
    g(0);
    ^
aa.cpp:5:6: note: candidate template ignored: substitution failure [with U = int
]
auto g(U x) -> decltype(f(x)){}
     ^
1 error generated.

比g++产生的错误更容易理解

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    • 2012-07-07
    相关资源
    最近更新 更多