This also happens sometimes with variables, because in C you have to declare the variable up at the top to be portable, whereas the code that uses it may be at the bottom of the function, so the programmers often just use the #ifdef at the point of use without an #ifdef at the declaration.
In C, this is true. If it's C++, you can declare the variable at (or nearer to) the point of use, which handily avoids this problem.
I had started using things like an UNUSED parameter, but there were so many instances of this in the project that I gave up on it and disabled that warning instead. There are also things such as GCC __attribute__ but that's not portable.
It doesn't need to be. You can set up an UNUSED macro which uses non-portable methods, depending on the compiler used. Here's one I found somewhere which I use to avoid this warning:
// suppress warnings for unused arguments
# define UNUSED(x) x __attribute__((unused))
# define UNUSED(x) /*@unused@*/ x
# define UNUSED(x) x
#endif // example: void dcc_mon_siginfo_handler(int UNUSED(whatsig))
And of course, the majority of these warnings often come from third party libraries that come as source, many of which are riddled throughout with #ifdefs for the various options they provide or architectures they support.
That's the problem I've found. You can add stuff like the above to avoid warnings in your own code, but if you're #including a library from somewhere else, you're stuck with whatever's in there, and turning on extra warnings can give you loads of warnings for things you have no power to fix. I wonder if there's some kind of compiler option to ignore warnings in third-party libraries?