Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 评论出一个#包括一个安全的方式,看看它是否#x27;没有必要吗?_C - Fatal编程技术网

C 评论出一个#包括一个安全的方式,看看它是否#x27;没有必要吗?

C 评论出一个#包括一个安全的方式,看看它是否#x27;没有必要吗?,c,C,我喜欢保持我的文件干净,所以我更喜欢取出我不需要的文件。最近我只是对include进行了注释,看看它是否编译时没有警告(-Wall-Wextra-pedantic,减去一些非常具体的警告)。我想如果它编译时没有警告,我就不需要它了 这实际上是一种安全的方法来检查是否需要include,或者它是否会引入UB或其他问题?我是否需要确保启用了任何特定警告以捕获潜在问题 n、 b.我实际上使用了Objective C和clang,因此任何特定于这些的东西都是值得赞赏的,但是考虑到Objective C的

我喜欢保持我的文件干净,所以我更喜欢取出我不需要的文件。最近我只是对include进行了注释,看看它是否编译时没有警告(
-Wall-Wextra-pedantic
,减去一些非常具体的警告)。我想如果它编译时没有警告,我就不需要它了

这实际上是一种安全的方法来检查是否需要include,或者它是否会引入UB或其他问题?我是否需要确保启用了任何特定警告以捕获潜在问题


n、 b.我实际上使用了Objective C和clang,因此任何特定于这些的东西都是值得赞赏的,但是考虑到Objective C的灵活性,我认为如果有任何问题,它将是一个通用的C东西。当然,C中的任何问题都会影响目标C。

通常只注释掉包含的头是安全的,这意味着:如果需要头,那么在删除它时会出现编译器错误,并且(通常)如果不需要头,代码仍然可以正常编译

这不应该在不检查标头以查看其添加内容的情况下进行,因为标头可能只提供可选的#define(或#undef),这将改变但不会中断程序的编译方式

唯一可以确保的方法是在不使用头的情况下构建代码(如果它首先能够构建),并运行适当的测试方案以确保其行为没有改变。

原则上,是的

例外情况是,如果两个头以某种隐藏方式交互。如果您:

  • 包括两个不同的标题,它们以不同的方式定义相同的符号
  • 这两个定义在语法上都是有效的,并且类型良好
  • 但是一个定义是好的,另一个在运行时中断程序
希望您的头文件不是这样构造的。这有点不太可能,但也不是不可想象的


如果我有很好的(单元)测试,我会更愿意这样做

一般来说,不会。很容易引入无声更改

假设
header.h
定义了一些宏,如

#define WITH_FEATURE_FOO
包含
header.h的C文件测试宏

#ifdef WITH_FEATURE_FOO
     do_this();
#else
     do_that();
#endif 
您的文件编译干净,并且启用了所有警告,无论是否包含
header.h
,但结果的行为不同。获得明确答案的唯一方法是分析标头定义/声明的标识符,并查看是否至少有一个标识符出现在预处理的C文件中

Gimpel提供的FlexeLint是一种实现这一点的工具。我这样说是没有报酬的,即使他们应该:-)如果你想避免花大钱,我一直采取的一种方法是将一个C文件编译成一个有头和没有头的对象文件,如果两者都成功检查相同的对象文件。如果它们相同,则不需要标题
(但请注意我们的include指令是否包装在
#ifdef
中,该指令由
-DWITH_FEATURE_FOO
选项启用)。

否。除了其他答案中已经提到的原因外,可能需要标题,而另一个标题间接包含它。如果您删除
#include
,您将不会看到错误,但在其他平台上可能会有错误。

我认为是的。如果存在
#ifdef
块,请确保检查任何可选编译方案。e、 g.操作系统定义了
#ifdef WINDOWS
,从这个意义上讲,它是安全的,如果它编译了,你应该可以,除非标题映射了名称(例如,如果它有
#define important#func(x,y,z)替代实现(x,y,z)
)。但是对于大多数通用的头文件,如果您从源文件中删除它,并且它仍然可以编译,那么其他头文件可能会包含它(因此它仍然在使用,但只是不那么可见),或者它不需要<代码>-Wredundant decls
也可能有用。否。假设您在一个系统上包含a.h和b.h。b.h本身可能包含a.h,而在另一个系统上不包含a.h。注释a.h在一个系统上有效,但在另一个系统上无效。系统文件应该少一些变化,但这确实发生了。最好的方法是,如果规范中说原型、定义等的主要位置在给定的标题中,我在使用该函数时会包含该标题,等等。请注意,它可能不是那么简单。考虑<代码> A.CPP < /代码>,包括<代码> B.H.<代码>和<代码> C.H.<代码>,以及<代码> B.H.<代码>,包括<代码> C.H.<代码>。假设事实上,
a.cpp
需要
b.h
c.h
,但
b.h
不需要任何东西。现在,如果删除“
a.cpp
includes
c.h
”部分,程序仍然可以编译,但逻辑上存在错误的依赖链:现在
a.cpp
依赖于
c.h
通过
b.h
a.cpp
是c源文件的系统很少。