[使用gcc
或clang
时,启用多个警告通常是一个好主意,-Wall
通常提供第一批警告。该批次很大,并且包含特定的警告-Wunused-function
。
现在,-Wunused-function
可用于检测不再调用的static
函数,这意味着它们无用,因此最好从源代码中删除。当应用“零警告”策略时,它不再是“可取的”,而是完全强制性的。
出于性能原因,可以将某些函数直接定义到头文件*.h
中,以便可以在编译时内联它们(不考虑任何LTO魔术)。通常将此类函数声明为static inline
。在过去,此类函数可能会被定义为宏,但是在适用的情况下,最好使它们成为static inline
函数(没有任何有趣的类型问题)。
确定,出于性能原因,现在我们有许多直接定义在头文件中的函数。包含此类头文件的单元没有义务使用其所有声明的符号。因此,可以合理地不调用头文件中定义的static inline
函数。
对于gcc
,很好。 gcc
将标记未使用的static
功能,但不会标记inline static
功能。但是,对于clang
,结果是不同的:如果单个单元未调用标头中声明的static inline
函数,则会触发-Wunused-function
警告。而且不需要很多标志即可到达:-Wall
就足够了。
一种解决方法是引入特定于编译器的扩展,例如__attribute__((unused))
,该扩展向编译器明确指出,标头中定义的函数不一定必须由其所有单元调用。好的,但是现在,以前干净的代码C99
包含某种形式的特定编译器扩展,这增加了可移植性和维护性。
因此,问题更多是关于这种选择的逻辑:为什么当未调用标头中定义的clang
函数时static inline
选择触发警告?在哪种情况下这是个好主意?
clang
提出什么建议来覆盖头文件中定义的内联函数的相对常见情况,而不要求使用编译器扩展名?
edit
:经过进一步调查,看来问题是不正确的。使用clang
linter应用选定的列表编译标志(-Wall
等),会在[[在编辑器中(VSCode)中触发警告。但是,当实际上使用clang
和完全相同的标志列表编译源代码时,将不显示“未使用的功能”警告。 到目前为止,在编辑器中可见的结果过去与在编译时发现的结果完全相同。这是我第一次看到与众不同。 因此问题似乎与短绒使用clang
生成警告列表的方式有关。这是一个更加复杂和具体的问题。
[好,抱歉,这实际上与预期不同。似乎使用clang
linter和选定的编译标志(-Wall
等)触发了[[在编辑器中警告。但是,当使用完全相同的标志编译源代码时,实际上不存在“未使用的功能”警告。到目前为止,在编辑器中可见的结果过去与在编译时发现的结果完全相同。这是我第一次目睹与众不同。因此,问题似乎与短绒使用clang
生成警告列表的方式有关。 [似乎比我意识到的还要复杂。
使用gcc或clang时,启用多个警告通常是一个好主意,并且-Wall通常提供第一批警告。该批次非常大,并且包含特定的...
gcc
或clang
时,启用多个警告通常是一个好主意,为此编写可移植代码的方法是基于编译器进行条件化:
#if __GNUC__ > 3
#define MayBeUnused __attribute__((__unused__))
#else
#define MayBeUnused
#endif
…
static inline void foo(some arguments) MayBeUnused;
GCC的预定义宏是documented here。我不知道3是否是您想要的版本。这只是一个例子。
请注意,unused
是用于标题的代码中的错误-可以由客户端源文件定义。 GCC接受带双下划线的属性,因此__attribute__((__unused__))
有效,并且不使用允许客户端源文件使用的标识符。