【问题标题】:gcc warns about unused static functions, but not static inline: is there a practical distinction?gcc 警告未使用的静态函数,但不是静态内联:有实际区别吗?
【发布时间】:2021-11-22 21:46:42
【问题描述】:

我的 gcc 版本(5.4)警告未使用的 static 函数,即使在使用 -Wall 的头文件中也是如此。如果定义相同的函数static inline 或简单地inline,它不会抱怨。

例如,文件unused.h中的以下函数:

static void foo() {}

...当包含在test.cpp 文件中时,如下所示:

#include "unused.h"

在使用-Wall 编译时生成以下编译器诊断:

In file included from test.cpp:11:0:
unused.h: At global scope:
unused.h:9:13: warning: ‘void foo()’ defined but not used [-Wunused-function]
 static void foo() {}
             ^

据我所知,通常的做法是包含具有许多实用功能的标头,但在任何给定的源文件中都可能会使用其中的一小部分。这种行为意味着我会收到关于我不使用的任何仅声明为 static 的函数的警告。

实际上,我可以简单地将这些更改为 static inline 以消除警告(或完全关闭特定警告,但我确实发现它有时很有用),但似乎大型实用程序功能不会从内联中受益的1 更符合逻辑地声明为static2

据我所知,未使用的 static 函数(就像 static inline)在编译翻译单元时会被 gcc 简单地删除,因此它们根本不会造成二进制大小或链接时间开销。

我在这里遗漏了什么吗?未使用的static 函数比static inline 更成问题是否有充分的理由?


1 是的,我知道这只是一个提示,但 gcc 实际上在 many cases 中得到了提示。

2 或者更好,只在头文件中声明并在 .cpp 文件中的其他位置定义 - 但这会禁止仅使用头文件,这有时很方便。

【问题讨论】:

  • 您是否有一个示例标头,我们可以使用它来重现此问题并测试可能的解决方案?
  • @tadman - 更新了问题。
  • 实现必须在头文件中有什么原因吗?你不能有一个单独的存根.cpp 文件和必要的实现吗?优化器可以决定如何处理它们。目前尚不清楚为什么将其标记为static。它是否在头文件的其他地方使用了一些方法和重要性,以至于它保持在文件的本地?
  • 如果您不想看到“未使用的功能”警告,我建议您禁用它
  • 更重要的是,您声称编译器只是忽略了inline,而我在最新版本的gcc 上展示了主流、最常用的优化级别,它显然没有.这就是我所要做的。表明 inline 在其他一些情况下可能没有什么不同,与其他一些编译标志完全无关。对于我的用例,它有所不同,我向您展示了实际代码,故事结束。

标签: c++ gcc compiler-warnings static-functions


【解决方案1】:

此类功能需要设置__attribute__((unused))属性。

【讨论】:

    【解决方案2】:

    警告是因为未使用的static 函数可能表示逻辑错误:如果从未调用过,为什么要编写这样的函数?

    但是,在头文件中包含static inline 函数是一种常见的习惯用法。这些函数可能仅由包含标题的某些翻译单元使用。如果编译器对没有使用其中一个函数的翻译单元发出警告,那会很烦人。

    如果你故意有一个未使用的staticinline 函数,你可能想要完全禁用警告,或者使用编译器特定的功能来禁止该函数的警告。


    有人问:“你为什么还要使用static inline?”。好吧,在新的 C++ 中,您大多不会使用它。但是,在 C 中,这样做是合理的。 (这是因为static inline 在 ISO C 和 GNU C 中的含义相同;但是没有 staticinline 在 ISO C 中的行为与在 GNU C 中的行为不同,因此默认为 static inline 只是避免了所有这些问题而不会出现问题-边)。

    人们可能会在.c.cpp 文件中包含的标题中使用static inline;或者他们只是将这种习惯从 C 延续到 C++。在后一种情况下,恕我直言,编译器警告一些虽然不必要但也不是错误或问题的东西会很烦人。

    【讨论】:

    • 好吧,我已经“编写”(或其他东西编写)了这样一个函数,原因与您从未调用过头文件中的大多数函数的原因相同:您包含一个头文件是因为您需要调用 至少一个功能 - 但不是全部!如果您实际上在 .cpp 文件中编写了您未调用的函数,则发出警告是有意义的,但如果您包含具有各种函数的头文件,则不会发出警告。
    • 为什么要将它们定义为静态的,而不仅仅是内联的?
    • @BeeOnRope 预处理器在编译器运行之前将所有相关的源文件组合成一个翻译单元;在生成警告时,“.cpp 文件”和“标题”没有分离。
    • @NeilButterworth - 因为 (a) inline 还暗示该函数可能适合内联,所以我更喜欢 static 用于我不想提示内联的函数(例如,大或非性能敏感函数)和(b)在单独与 C inline 共享的头文件中不起作用(有时需要一个外联函数,因此它不是仅头文件等)。不要误会我的意思,解决方案是static inline,但我很好奇是否只有-static 函数是某种反模式。
    • @BeeOnRope 够公平的。我扩展了我的答案以涵盖 Neil Butterworth 的观点
    猜你喜欢
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 2016-04-27
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多