Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use GCC diagnostic pragma with C++ template functions?

I would like to use g++ and -Werror, so I have now to disable warnings for 3rd-party libraries I have no control of. The solution provided by http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html works very well, allowing simply to wrap the includes of 3rd party headers with pragmas. Unfortunately, that did no longer work for me in a certain setup where templates are involved. I created the following minimal example of where this approach did not work as expected:

Source file 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
}

and the header hdr.hpp

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

compiled using Makefile

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

will produce the following compiler error

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

Note that explicit instantiation in main.cpp directly after including the header did not work, and wrapping the call to the template function in main.cpp did not work either. What was puzzling that putting #pragma GCC diagnostic ignored "-Wunused-parameter" in front of the main function silenced the compiler, whilst then adding #pragma GCC diagnostic error "-Wunused-parameter" at the very end of the file caused the compiler to produce the error again. How to solve this puzzle?

(Note, there are dozens of threads about this pragma, but I could not find anyone that involved such a setup)

like image 971
Julius Avatar asked Jun 03 '11 13:06

Julius


2 Answers

The issue is that the instantiation of the template is compiled when you use it, not when it is parsed by the compiler in the header file so it will not issue the warning until it replaces T by int and parses it as a regular function outside the context of the pragma silencing.

like image 85
David Avatar answered Sep 19 '22 20:09

David


The usual way to indicate that you don't intend to use a parameter is to not give it a name:

template<typename T> 
int mytemplatefunc(T /* t */) 
{ return 42; } 

int mystandardfunc(int /* i */) 
{ return 53; } 
like image 25
Bo Persson Avatar answered Sep 18 '22 20:09

Bo Persson