5

在 Linux 上,确定#includeC++ 项目所需的必要语句的快速方法是什么?

我的意思是,假设有人给了你一个网络片段,但没有提供必要的#include 语句。有没有一种方法可以让您运行 Linux 命令或编译器命令选项并确定缺少哪些函数或类,并且作为奖励,确定我可能在头文件中包含这些东西的硬盘驱动器上的位置。

4

5 回答 5

4

基本上,您需要一些分析器来解析您的源代码和标头并构建一个完整的依赖关系图,它最终会吐出供您进一步阅读和处理。

为此,我会遵循 john 对 g++ 和 Clang 的建议,但我非常怀疑他们是否得到了所需。

至少使用 g++,您实际上可以做的是打印出已经存在的包含的图表。使用 -H 选项打印树或使用 -M 获取列表。

我还建议您参考这个相关主题:跟踪#include 依赖项的工具

不完全是您想要的,但那里提到的工具可能会有所帮助。

于 2013-09-20T19:25:36.613 回答
2

我认为Clang 的“include-what-you-use”工具就是你想要的。

于 2013-09-21T01:05:09.897 回答
-1

我知道在程序中找到未定义标识符的最好方法就是尝试编译它。根据您使用的编译器的具体情况,您可以简单地将 GCC 或 Clang 的输出通过管道传输到 grep 中,查找诸如“未声明的标识符”之类的短语。</p>

至于确定符号的定义位置,我建议您首先查看Ctags以解析您的系统标头(最好使用 Makefile 进行管理)并使用生成的标签表来查找 grep 从 GCC 捕获的任何内容。

于 2013-09-20T23:41:48.803 回答
-1

如果,必要时你的意思是最小(即如果A包括B,B包括C,那么A不需要包括C)我不知道快速的方法。

然而,一种好的方法是让每个 cpp 文件首先包含它自己的头文件(在任何预编译的头文件之后)。这样可以确保每个头文件都(直接或间接地)包含它需要定义在标题。

此外,一个合理大小的项目应该设计在层中,这样层 A 知道/依赖于层 B,而层 B 依赖于层 C 等,但较低层从不包括较高层(即 C 从不包括来自 A 层的任何东西)

在这种情况下,每个 cpp 或 hpp 中的包含应按层顺序(A、B、C)。如果您这样做,则很容易检查是否可以消除任何 C 层标头(暂时将它们注释掉),因为它们之前的包含之一已经包含它们。这种情况经常发生,并且可以显着减少每个文件中#include 的数量。

说了这么多,这是一个比以前更不重要的问题,因为编译器更聪明了。#pragma once 和预编译头文件的组合可以减少构建时间,而无需您花费大量时间优化包含。

于 2013-09-20T18:37:38.393 回答
-2

最快的方式……你不应该这么想。

https://stackoverflow.com/a/18544093/2112028

我在那里写了一个可爱的(我很自豪:P)答案,谈论链接是如何工作的(使用模板)并证明它是有效的等等,理解这一点。

#include 指令的目标是创建一个“翻译单元”,其中声明了每个符号(即使未定义)我的答案中有一个示例,我只需将原型复制并粘贴到代码文件中,而不是使用包含。

如果你使用一种叫做“Header guards”的东西,你不应该担心“最快”的方式(这些在底部简要提到,但这还不够详细)它们是这样的:

#ifndef __WHATEVER_H
#define __WHATEVER_H

/*Your code here*/

#endif

因此,现在您可以随意多次包含“whatever.h”。第一次在翻译单元中,将定义 __WHATEVER_H,因此包含它的下一个文件(无论正在编译的文件中有多少包含深度)将为空。因为#ifndef 和#endif 之间的所有内容都将消失。

希望这可以帮助。

此外,如果您有不必要的输入,请使用 -Wextra 和 -Wall,GCC 会告诉您未使用的函数、typedef 等。你可以使用编译错误推送和弹出的东西来控制它。例如 wxWidget 的头文件可能包含很多未使用的东西,因此您将警告压入堆栈,删除未使用的警告标志,包含文件,弹出警告堆栈(重新打开它们),少了数千行警告。

于 2013-09-20T18:49:21.790 回答