I want to test for the use of a constant in a source file and if it is used, stop compilation.
The constant in question is defined in a generic driver file which a number of driver implementations inherit from. However, it's use has been deprecated so subsequent updates to each drivers should switch to using a new method call and not the use of this const value.
This doesn't work obviously
#ifdef CONST_VAR
#error "custom message"
#endif
How can I do this elegantly? As It's an int, I can define CONST_VAR as a string and let it fail, but that might make it difficult for developers to understand what actually went wrong. I was hoping for a nice #error type message.
Any suggestions?
The Poison answer here is excellent. However for older versions of VC++ which don't support [[deprecated]] I found the following works.
Use [[deprecated]] (C++14 compilers) or __declspec(deprecated)
To treat this warning as an error in a compilation unit, put the following pragma near the top of the source file.
#pragma warning(error: 4996)
e.g.
const int __declspec(deprecated) CLEAR_SOURCE = 0;
const int __declspec(deprecated("Use of this constant is deprecated. Use ClearFunc() instead. See: foobar.h"));
AFAIK, there's no standard way to do this, but gcc and clang's preprocessors have #pragma poison which allows you to do just that -- you declare certain preprocessor tokens (identifiers, macros) as poisoned and if they're encountered while preprocessing, compilation aborts.
#define foo
#pragma GCC poison printf sprintf fprintf foo
int main()
{
sprintf(some_string, "hello"); //aborts compilation
foo; //ditto
}
For warnings/errors after preprocessing, you can use C++14's [[deprecated]] attribute, whose warnings you can turn into errors with clang/gcc's -Werror=deprecated-declarations .
int foo [[deprecated]];
[[deprecated]] int bar ();
int main()
{
return bar()+foo;
}
This second approach obviously won't work for on preprocessor macros.
what does this macro mean ? I just find the following macro in source files:
#define UNUSED(x) ((x)=(x))
It is probably there to suppress compiler warnings of unused variables/arguments to functions. You could also use this:
// C++ only
void some_func(int /*x*/)
Or
// C and C++
void some_func(int x)
{
(void)x;
}
Or your compiler may support a flag to do so, but these are portable and won't skip over valid warnings.
Use it to get rid of any compiler warning referring an unused variable.
Some compilers issue a warning about unused variables - variables that are defined but never referenced. Sometimes you have code that references a variable only under some conditional ifdefs (only on some platforms or only in debug) and it is inconvenient to duplicate those conditions at the point the variable is defined. A macro like this can be used to suppress the unused variable warning in such cases.
It silence the compiler from complaining that a variable is not used.
Other ways to do it :
completely remove the variable : void foo( int )
out comment the variable : void foo( int /* value */ )
use that macro : void foo( int value ){ UNUSED(value); }
How can I disable the following warning in C++ in minGW?
warning: unused variable 'x' [-Wunused-variable]
In Eclipse CDT, I can't locate the warning number:
../src/subfolder/ClassTwo.cpp:20:8: warning: unused variable 'x' [-Wunused-variable]
I tried doing this:
#pragma warning(push)
#pragma warning(disable: ?) //which number?
#include "subfolder/ClassTwo.h"
#pragma warning(pop)
But it didn't work.
My questions:
How can I get the warning number of this in Eclipse CDT?
How should the pragma directive be written?
Since it's NEARLY always easy to fix "unused variable" warnings, I'd very much prefer to fix the actual code than try to patch it up with pragmas (which may hide other, future errors too - for example you add a new function:
int foo(int x, int y)
{
return x * x;
}
Oops, that's a typo, it's supposed to be return x * y; - a warning would give you indication that this is the case.
Unused parameters, as someone mentioned, are dealt with by removing the name of the parameter:
int foo(int x, int) // Second parameter, y is not used
{
return x * x;
}
If it's a local variable, then you can use (void)y (perhaps in aa macro) to "fake use it":
int bar(int x)
{
int y; // Not used.
(void)y;
}
or
#define NOT_USED(x) (void)(x)
int bar(int x)
{
int y; // Not used.
NOT_USED(y);
}
It looks like the output from clang. You can achieve the same using clang using the approach outlined here: http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
#include "subfolder/ClassTwo.h"
#pragma clang diagnostic pop
If that's your source file, then just fix the warning.
For GCC, you can use this: Selectively disable GCC warnings for only part of a translation unit?
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#include "subfolder/ClassTwo.h"
#pragma GCC diagnostic pop
Of course, that will leave you with a good amount of pragma noise -- debatable if that is a bad thing =)
You seem to be using Microsoft C++ style pragma syntax with GCC compiler. The concept of "warning number" (at least in that format) is also Microsoft C++ specific. In other words, this should not work in GCC.
There's no standard syntax for disabling/enabling warnings, so each compiler will use its own. That means that there's no way to do it "in C++" (quoting your title). There are only ways to do it in each specific compiler. You have to consult your compiler docs for that.
In GCC you should be able to do it through command-line options -Wno-unused-variable do disable all such warnings for the entire translation unit. Also, in GCC you can actually selectively mark variables as unused through __attribute__((unused)) to suppress warnings for that specific variable.
http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes
I ran into this today in an if and after looking into it found that all these are all valid statements that generate the C4353 . My only guess is that this is the old way of doing noop in C. Why is this not an error. When would you use this to do anything useful.
int main()
{
nullptr();
0();
(1 == 2)();
return 0;
}
Using constant 0 as a function expression is an extension that is specific to Microsoft. They implemented this specifically because they saw a reason for it, which explains why it's wouldn't make sense to treat it as an error. But since it's non-standard, the compiler emits a warning.
You are correct that it is an alternative to using __noop().
All of these :
nullptr();
0();
(1 == 2)();
are no-op statements (meaning they don't do anything).
btw I hope you are not ignoring warnings. Most of the time it is a good practice to fix all warnings.
As explained in the C4353 warning page and in the __noop intrinsic documentation, the use of 0 as a function expression instructs the Microsoft C++ compiler to ignore calls to the function but still generate code that evaluates its arguments (for side effects).
The example given is a trace macro that gets #defined either to __noop or to a print function, depending on the value of the DEBUG preprocessor symbol:
#if DEBUG
#define PRINT printf_s
#else
#define PRINT __noop
#endif
int main() {
PRINT("\nhello\n");
}
The MSDN page for that warning has ample explanation and a motivating example:
// C4353.cpp
// compile with: /W1
void MyPrintf(void){};
#define X 0
#if X
#define DBPRINT MyPrint
#else
#define DBPRINT 0 // C4353 expected
#endif
int main(){
DBPRINT();
}
As you can see it is to support archaic macro usage.
I have a cross platform application and in a few of my functions not all the values passed to functions are utilised. Hence I get a warning from GCC telling me that there are unused variables.
What would be the best way of coding around the warning?
An #ifdef around the function?
#ifdef _MSC_VER
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal qrLeft, qreal qrTop, qreal qrWidth, qreal qrHeight)
#else
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal /*qrLeft*/, qreal /*qrTop*/, qreal /*qrWidth*/, qreal /*qrHeight*/)
#endif
{
This is so ugly but seems like the way the compiler would prefer.
Or do I assign zero to the variable at the end of the function? (which I hate because it's altering something in the program flow to silence a compiler warning).
Is there a correct way?
You can put it in "(void)var;" expression (does nothing) so that a compiler sees it is used. This is portable between compilers.
E.g.
void foo(int param1, int param2)
{
(void)param2;
bar(param1);
}
Or,
#define UNUSED(expr) do { (void)(expr); } while (0)
...
void foo(int param1, int param2)
{
UNUSED(param2);
bar(param1);
}
In GCC and Clang you can use the __attribute__((unused)) preprocessor directive to achieve your goal.
For example:
int foo (__attribute__((unused)) int bar) {
return 0;
}
C++17 now provides the [[maybe_unused]] attribute.
http://en.cppreference.com/w/cpp/language/attributes
Quite nice and standard.
C++17 Update
In C++17 we gain the attribute [[maybe_unused]] which is covered in [dcl.attr.unused]
The attribute-token maybe_unused indicates that a name or entity is possibly intentionally unused. It shall
appear at most once in each attribute-list and no attribute-argument-clause shall be present.
...
Example:
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
[[maybe_unused]] bool thing2) {
[[maybe_unused]] bool b = thing1 && thing2;
assert(b);
}
Implementations should not warn that b is unused, whether or not NDEBUG is defined. —end example ]
For the following example:
int foo ( int bar) {
bool unused_bool ;
return 0;
}
Both clang and gcc generate a diagnostic using -Wall -Wextra for both bar and unused_bool (See it live).
While adding [[maybe_unused]] silences the diagnostics:
int foo ([[maybe_unused]] int bar) {
[[maybe_unused]] bool unused_bool ;
return 0;
}
see it live.
Before C++17
In C++11 an alternative form of the UNUSED macro could be formed using a lambda expression(via Ben Deane) with an capture of the unused variable:
#define UNUSED(x) [&x]{}()
The immediate invocation of the lambda expression should be optimized away, given the following example:
int foo (int bar) {
UNUSED(bar) ;
return 0;
}
we can see in godbolt that the call is optimized away:
foo(int):
xorl %eax, %eax
ret
Your current solution is best - comment out the parameter name if you don't use it. That applies to all compilers, so you don't have to use the pre-processor to do it specially for GCC.
An even cleaner way is to just comment out variable names:
int main(int /* argc */, char const** /* argv */) {
return 0;
}
gcc doesn't flag these warnings by default. This warning must have been turned on either explicitly by passing -Wunused-parameter to the compiler or implicitly by passing -Wall -Wextra (or possibly some other combination of flags).
Unused parameter warnings can simply be suppressed by passing -Wno-unused-parameter to the compiler, but note that this disabling flag must come after any possible enabling flags for this warning in the compiler command line, so that it can take effect.
A coworker just pointed me to this nice little macro here
For ease I'll include the macro below.
#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*#unused#*/ x
#else
# define UNUSED(x) x
#endif
void dcc_mon_siginfo_handler(int UNUSED(whatsig))
macro-less and portable way to declare one or more parameters as unused:
template <typename... Args> inline void unused(Args&&...) {}
int main(int argc, char* argv[])
{
unused(argc, argv);
return 0;
}
Using preprocessor directives is considered evil most of the time. Ideally you want to avoid them like the Pest. Remember that making the compiler understand your code is easy, allowing other programmers to understand your code is much harder. A few dozen cases like this here and there makes it very hard to read for yourself later or for others right now.
One way might be to put your parameters together into some sort of argument class. You could then use only a subset of the variables (equivalent to your assigning 0 really) or having different specializations of that argument class for each platform. This might however not be worth it, you need to analyze whether it would fit.
If you can read impossible templates, you might find advanced tips in the "Exceptional C++" book. If the people who would read your code could get their skillset to encompass the crazy stuff taught in that book, then you would have beautiful code which can also be easily read. The compiler would also be well aware of what you are doing (instead of hiding everything by preprocessing)
I have seen this instead of the (void)param2 way of silencing the warning:
void foo(int param1, int param2)
{
std::ignore = param2;
bar(param1);
}
Looks like this was added in C++11
Lol! I dont think there is another question on SO that reveal all the heretics corrupted by Chaos better that this one!
With all due respect to C++17 there is a clear guideline in C++ Core Guidelines. AFAIR, back in 2009 this option was available as well as today. And if somebody says it is considered as a bug in Doxygen then there is a bug in Doxygen
First off the warning is generated by the variable definition in the source file not the header file. The header can stay pristine and should, since you might be using something like doxygen to generate the API-documentation.
I will assume that you have completely different implementation in source files. In these cases you can either comment out the offending parameter or just write the parameter.
Example:
func(int a, int b)
{
b;
foo(a);
}
This might seem cryptic, so defined a macro like UNUSED. The way MFC did it is:
#ifdef _DEBUG
#define UNUSED(x)
#else
#define UNUSED(x) x
#endif
Like this you see the warning still in debug builds, might be helpful.
Is it not safe to always comment out parameter names? If it's not you can do something like
#ifdef _MSC_VER
# define P_(n) n
#else
# define P_(n)
#endif
void ProcessOps::sendToExternalApp(
QString sAppName, QString sImagePath,
qreal P_(qrLeft), qreal P_(qrTop), qreal P_(qrWidth), qreal P_(qrHeight))
It's a bit less ugly.
Using an UNREFERENCED_PARAMETER(p) could work. I know it is defined in WinNT.h for Windows systems and can easily be defined for gcc as well (if it doesn't already have it).
UNREFERENCED PARAMETER(p) is defined as
#define UNREFERENCED_PARAMETER(P) (P)
in WinNT.h.
Use compiler's flag, e.g. flag for GCC:
-Wno-unused-variable
In C++11, this is the solution I'm using:
template<typename... Ts> inline void Unreferenced(Ts&&...) {}
int Foo(int bar)
{
Unreferenced(bar);
return 0;
}
int Foo2(int bar1, int bar2)
{
Unreferenced(bar1, bar2);
return 0;
}
Verified to be portable (at least on modern msvc, clang and gcc) and not producing extra code when optimizations are enabled.
With no optimization, the extra function call is performed and references to the parameters are copied to the stack, but there are no macros involved.
If the extra code is an issue, you can use this declaration instead:
(decltype(Unreferenced(bar1, bar2)))0;
but at that point, a macro provides better readability:
#define UNREFERENCED(...) { (decltype(Unreferenced(__VA_ARGS__)))0; }
This works well but requires C++11
template <typename ...Args>
void unused(Args&& ...args)
{
(void)(sizeof...(args));
}
You can use __unused to tell the compiler that variable might not be used.
- (void)myMethod:(__unused NSObject *)theObject
{
// there will be no warning about `theObject`, because you wrote `__unused`
__unused int theInt = 0;
// there will be no warning, but you are still able to use `theInt` in the future
}
I found most of the presented answers work for local unused variable only, and will cause compile error for unused static global variable.
Another macro needed to suppress the warning of unused static global variable.
template <typename T>
const T* UNUSED_VARIABLE(const T& dummy) {
return &dummy;
}
#define UNUSED_GLOBAL_VARIABLE(x) namespace {\
const auto dummy = UNUSED_VARIABLE(x);\
}
static int a = 0;
UNUSED_GLOBAL_VARIABLE(a);
int main ()
{
int b = 3;
UNUSED_VARIABLE(b);
return 0;
}
This works because no warning will be reported for non-static global variable in anonymous namespace.
C++ 11 is required though
g++ -Wall -O3 -std=c++11 test.cpp
void func(void *aux UNUSED)
{
return;
}
smth like that, in that case if u dont use aux it wont warn u
I don't see your problem with the warning. Document it in the method/function header that compiler xy will issue a (correct) warning here, but that theses variables are needed for platform z.
The warning is correct, no need to turn it off. It does not invalidate the program - but it should be documented, that there is a reason.