GCC 4.6中奇怪的诊断实践行为

时间:2012-03-23 00:46:48

标签: c gcc warnings pragma gcc4

我有一个C程序,其中包含一些尚未使用的静态函数。我想禁用这些特定功能的警告。我不想禁用所有-Wunused-function警告。我正在使用GCC 4.6。具体做法是:

ek@Apok:~/source$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我遵循文档中的建议(使用pushpop),但我无法让它工作。

我已经创建了一些简化的源代码来调查问题。我正在用gcc -Wall -o pragma pragma.cpragma.c)编译它们。我的pragma.c的第一个版本如下所示:

void foo(int i) { }
static void bar() { }
int main() { return 0; }

正如所料,我在编译时得到了这个:

pragma.c:3:13: warning: ‘bar’ defined but not used [-Wunused-function]

同样如预期的那样,我可以像这样禁用警告(然后编译成功地静默):

#pragma GCC diagnostic ignored "-Wunused-function"
void foo(int i) { }
static void bar() { }
int main() { return 0; }

然而,我试过这个:

void foo(int i) { }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static void bar() { }
#pragma GCC diagnostic pop
int main() { return 0; }

当我编译时,我收到了原始警告:

pragma.c:4:13: warning: ‘bar’ defined but not used [-Wunused-function]

删除pop删除警告:

void foo(int i) { }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static void bar() { }
int main() { return 0; }

但我需要一种方法来禁用针对特定代码段的警告。我无法做到这一点。

我很难想象这可能是什么样的行为...但是很多其他人都使用过这个版本的GCC,如果这是一个bug,它似乎不太可能会进入发布版本。 / p>

尽管如此,我仍然无法看到这种行为与文档是如何一致的,该文档说“在行之后发生的编译指示不会影响由该行引起的诊断。”

有谁知道我做错了什么? (或者,如果没有,是否有人有关于该问题的更多信息,例如错误报告的链接和/或有关可能的解决方法的信息。)

1 个答案:

答案 0 :(得分:14)

这适用(gcc版本4.6.1):

#ifdef __GNUC__
#define SUPPRESS_NOT_USED_WARN __attribute__ ((unused))
#else
#define SUPPRESS_NOT_USED_WARN
#endif

void foo() {  }
SUPPRESS_NOT_USED_WARN static void bar() { }
int main() { return 0; }

/* or
static void SUPPRESS_NOT_USED_WARN bar() { }
 etc. */

/* but not, undefined declarations:
SUPPRESS_NOT_USED_WARN static void bar();
*/

(编辑:)
GCC v4.2.4 doc. 5.32 Specifying Attributes of Variables

  

未使用
  附加到变量的此属性表示该变量可能未使用。 GCC不会对此变量发出警告。

(Edit.2 :)
GCC v4.2.4 doc. 5.25 Declaring Attributes of Functions(更正确的链接,功能,抱歉。)

  

未使用
  附加到函数的此属性意味着该函数可能未使用。 GCC不会对此功能发出警告。


说到pragma pushpop等,文档说:

GCC doc. 6.57.10 Diagnostic Pragmas

  

修改诊断的处置。请注意,并非所有诊断都可以修改;目前只有警告(通常由`-W ......'控制)可以控制,而不是所有警告。使用-fdiagnostics-show-option确定哪些诊断是可控制的,哪个选项控制它们。

它说; “而不是所有人”-Wunused-function似乎是不愿意被压制的人之一。默认情况下,似乎启用了选项fdiagnostics-show-option。 (给出启用错误/警告的标志。)。

在命令行中使用-Wno-unused-function会禁用它,但当然对所有人来说都是禁用它,而不仅仅是代码中直接指定的那些。

如果你说:

  

gcc -Wunused-function -o o mycode.c

你仍然会得到警告,所以它与-Wall没有任何关系,将编译过程设置在一个不能工作的特殊状态。


作为一个例子,这有效:

int foo(int i) { return i; }

int main() {
    int a;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(a);
#pragma GCC diagnostic pop

    return 0;
}