【问题标题】:How to detect declared but undefined functions in C++?如何检测 C++ 中已声明但未定义的函数?
【发布时间】:2014-04-21 16:56:42
【问题描述】:

以下编译、链接和运行都很好(在 Xcode 5.1 / clang 上):

#include <iostream>

class C { int foo(); };

int main(int argc, const char * argv[])
{
    C c;
    cout << "Hello world!";
}

但是,C::foo() 没有在任何地方定义,只是声明了。我没有收到任何编译器或链接器警告/错误,显然是因为 C::foo() 从未在任何地方引用。

有什么方法可以发出警告,即在 整个程序 中即使声明了 C::foo() 也不存在定义?错误实际上会更好。

谢谢!

【问题讨论】:

  • 也许静态分析工具可以做到这一点,但我不知道。当然,该定义有多种可能的来源,因此存在复杂性。
  • 通常的做法是定义(私有)方法而不实现禁止复制(在 C++03 中,直到 = 删除)...
  • 如果您不介意使用第三方工具,那么 cppclean 看起来就像您想要的那样。在它检查的事物列表中,它包括Unnecessary function declarations
  • 这是 "If a tree falls in a forest..." 问题的 C++ 版本。除非使用任何静态分析工具,否则链接器是唯一有兴趣检测这一点的实体。但由于它只对将定义与引用这些定义的事物联系起来感兴趣,因此它对检测它不感兴趣。所以需要有人在森林里。
  • @oxfordatnight 我知道您是对此感兴趣的“实体”。 :-) 我的意思是编译过程中没有人对它感兴趣,所以你需要求助于某种第三方工具。 (这可能不会告诉你任何你不知道的事情;我只是想确保每个人都在同一个页面上。)

标签: c++ xcode


【解决方案1】:

它不容易实现是有充分理由的。一组头文件可以声明许多函数,其中一些由 additional 库提供。您可能希望#include 这样的标头而不使用所有这些函数(例如,如果您只想使用一些#define-d 常量)。

或者,拥有一些标头并仅实现(在您的库中)由标头文件定义的 API 的子集是合法的。

C++ 或 C 头文件也可以定义潜在插件定义的代码接口,用于通常在没有插件的情况下运行的程序。许多接受插件的程序都在其头文件中声明了插件接口。

如果您真的想进行这样的检查,您可能会考虑使用MELT 自定义GCC;但是,目前实施这样的检查并非易事(而且您还需要优化链接时间)。

【讨论】:

  • 这不是答案,真的。此外,lint pass 和静态分析工具通常可以配置为仅报告给定目录列表中文件的错误,从而忽略第 3 方依赖项。
  • 这是一个有趣的观点。我可以看到这个问题(这意味着我总是必须链接到我包含其标题的库)。比如说,这对 Boost 来说是个问题。不过——如果我愿意的话,能做些检查就好了。
【解决方案2】:

也许尝试调用实现映射中的所有函数并添加一个 try catch,如果它们出现段错误,则会发出一些警告。

【讨论】:

  • Segfault 是未定义行为的结果,try-catch 无法捕获 UB。
【解决方案3】:

你不知道。或者说,这不是编译器的工作

我想我只是在重复其他人在 cmets 中所说的话,但是:

  • 它实际上是一个特性(参见未实现的私有构造函数)
  • 这并没有真正的帮助,因为这里的“错误”是在提交代码之前没有进行适当的代码清理,而未实现的 未使用的函数实际上是你最小的问题.其他没有清理的东西怎么办?在我看来,实现和未使用的功能的可能性同样高,而且或多或少都是一团糟。

与其担心这种特殊情况,我会检查这是否只是一次故障,或者您的开发团队是否可以改进一些程序以防止将来发生此类事情。

【讨论】:

    【解决方案4】:

    就诸如 C++ 之类的语言而言,检测和报告未定义的函数将破坏它提供的一项重要功能。虚函数/纯虚函数是C++实现运行时多态性的重要机制之一。

    如果您正在开发一个供其客户使用的库,您可能已经声明了但未定义的虚函数。您可以将定义留给它的客户。在这种情况下,如果编译器要报告这些未定义的函数,那将无济于事。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      相关资源
      最近更新 更多