如何在C++模板函数中使用GCC诊断编译指示符?

6
我想使用g++和-Werror,所以现在我需要禁用我无法控制的第三方库的警告。 http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html提供的解决方案非常好,可以简单地使用pragma包装第三方头文件。不幸的是,在涉及模板的某些设置中,这种方法对我不再起作用。我创建了以下最小示例,其中此方法未按预期工作:

源文件main.cpp

#pragma GCC diagnostic ignored "-Wunused-parameter"
#include "hdr.hpp"
#pragma GCC diagnostic error "-Wunused-parameter"
int main() {
    return mytemplatefunc(2) + mystandardfunc(3); // will print ONLY ONE warning
}

并且包含头文件hdr.hpp

template<typename T>
int mytemplatefunc(T t) {
    return 42;
}
int mystandardfunc(int i) {
    return 53;
}

使用Makefile编译

CPPFLAGS+=-Wunused-parameter -Werror
main: main.cpp

将会产生以下编译器错误。
g++  -Wunused-parameter -Werror   main.cpp   -o main
In file included from main.cpp:3:
hdr.hpp: In instantiation of ‘int mytemplatefunc(T) [with T = int]’:
main.cpp:29:   instantiated from here
hdr.hpp:2: error: unused parameter ‘t’
make: *** [main] Error 1
shell returned 2

请注意,直接在 main.cpp 中包含头文件后进行显式实例化并不起作用,而在 main.cpp 中包装模板函数的调用也不起作用。令人困惑的是,在主函数前加上 #pragma GCC diagnostic ignored "-Wunused-parameter" 可以使编译器静音,但在文件的 最后 添加 #pragma GCC diagnostic error "-Wunused-parameter" 会导致编译器再次产生错误。如何解决这个谜题?
(注意,有关此 pragma 的讨论有数十个帖子,但我找不到涉及这种设置的任何帖子)

从提供的链接中可以得知,“GCC跟踪每个#pragma的位置,并根据源文件中的状态发出诊断。因此,出现在某一行之后的#pragma不会影响由该行引起的诊断。”所以,即使您只是在代码末尾重新打开错误,如果仍然遇到问题...您是否尝试将第二个#pragma作为“diagnostic warning”而不是“diagnostic error”?如果它仍然报告为错误而不是警告,则可能需要检查您的头文件中的#pragma。 - JAB
不,那么它将报告警告。但这并不符合我的要求。整个想法是要有错误而不是警告(-Werror),这样我就会收到编译失败的通知,而不必手动扫描多页编译器输出(如果我必须区分我可以实际处理的警告和我必须忽略的警告,那将是困难的)。我认为hdr.hpp是我无法控制的(想象一下它是第三方的)。 - Julius
http://www.spinics.net/lists/gcchelp/msg30702.html 似乎与这个问题有关。我正在使用gcc 4.4.5,它似乎不支持在比文件级别更细的范围内使用这样的#pragma。在进一步的测试中,我放弃了头文件并尝试了-Wuninitialized,但它的行为也很奇怪。 - Julius
2个回答

5
问题在于模板的实例化是在使用时编译的,而不是在头文件中解析时编译的,因此直到将T替换为int并将其解析为常规函数时才会发出警告,而不是在pragma静音的上下文之外。

2
通常表示您不打算使用参数的方法是不给它命名:
template<typename T> 
int mytemplatefunc(T /* t */) 
{ return 42; } 

int mystandardfunc(int /* i */) 
{ return 53; } 

是的,那个方法可行!实际上,在我的描述中我应该包括头文件实际上是不受我控制的,所以我不能修复头文件,而必须在我包含该头文件的代码部分中消除警告。 - Julius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接