Selectively suppress "unused variable" warnings for unused lambdas - c++

Is there any way to suppress "unused variable" warnings for a specific file, namespace, or specific variable?
I ask because I have a namespace containing a big list of lambda functions. Some are not used now, but might be used in time. If these were regular free functions, I would not be warned if some were unused. However, because they are lambdas, I end up with a stack of compiler warnings.
I do not want to use a compiler flag to remove all of this type of warning, as normally, it is very useful to have the compiler catch unused variables. However, a stack of warnings about unused utility functions adds noise to otherwise useful information.

There are two approaches that come to mind. First of all, most build environments enable per-source compiler flags, so you should be able to turn off that warning just for the single file where all those lambdas are defined.
Then there is a general approach to silence such warnings for single variables: use it, but not really do anything with it. On some compilers this can be achieved with a simple cast to void:
auto x = /* ... */;
(void) x;
But more effective is defining a simple function that makes it look (for the compiler) as if the variable was used:
template <class T>
void ignore_unused(T&) {}
//later...
auto x = /* ... */;
ignore_unused(x);
Note the parameter has no name, so the compiler will not complain about that one to be unused.
The idea is pretty common: do something with the variable that effectively makes no operation but silences the static analyzer that emits the "unused variable" warning.
Boost has a similar function, boost::ignore_unused_variable_warning()
For more information, see Herb Sutter's blog.

In C++ you can static_cast anything to void.
What is the use of such a cast if it does not produce any side effects or a value one might ask?
Precisely to tell the compiler that an object is "used" in a portable way.
So,
auto x = /*...*/;
static_cast<void>(x);

Lambdas are just syntactic sugar for functors. Functors are a type of object (one that has operator() overloaded). So the compiler will warn if that variable (object) goes unused.
I recommend the block-comment method for hushing the compiler ;). Other than that, there's not much you can do to selectively and cleanly silence the compiler in the general case.
Note that if you have a more specific case, such as passing arguments in a function, you can make the argument nameless if you do not use it. Another thing you could do is put a (void)var reference somewhere in your code (although this is cheating; now you've referenced it!). Lastly, if your compiler supports it (the almighty GCC does), you might try using the __attribute__((unused)) preprocessor directive (use [[gnu::unused]] for Clang).
Depending on your situation, these suggestions may or may not help.

How about hiding the lambdas inside of generators. That way they don't even get created unless they are used. So instead of:
auto add_one= [](int x){ return x + 1 } ;
Use:
std::function<int(int)> gen_addone(void)
{
static auto l_= [](int x){ return x + 1 ; } ;
return l_ ;
}
Sorry, you'll have to wait till c++1y for automatic return type deduction.

Related

Why gcc and clang both don't emit any warning?

Suppose we have code like this:
int check(){
int x = 5;
++x; /* line 1.*/
return 0;
}
int main(){
return check();
}
If line 1 is commented out and the compiler is started with all warnings enabled, it emits:
warning: unused variable ‘x’ [-Wunused-variable]
However if we un-comment line 1, i.e. increase x, then no warning is emitted.
Why is that? Increasing the variable is not really using it.
This happen in both GCC and Clang for both c and c++.
Yes.
x++ is the same as x = x+1;, the assignment. When you are assigning to something, you possibly can not skip using it. The result is not discarded.
Also, from the online gcc manual, regarding -Wunused-variable option
Warn whenever a local or static variable is unused aside from its declaration.
So, when you comment the x++;, it satisfies the condition to generate and emit the warning message. When you uncomment, the usage is visible to the compiler (the "usefulness" of this particular "usage" is questionable, but, it's an usage, nonetheless) and no warning.
With the preincrement you are incrementing and assigning the value to the variable again. It is like:
x=x+1
As the gcc documentation says:
-Wunused-variable:
Warn whenever a local or static variable is unused aside from its declaration.
If you comment that line you are not using the variable aside of the line in which you declare it
increasing variable not really using it.
Sure this is using it. It's doing a read and a write access on the stored object. This operation doesn't have any effect in your simple toy code, and the optimizer might notice that and remove the variable altogether. But the logic behind the warning is much simpler: warn iff the variable is never used.
This has actually the benefit that you can silence that warning in cases where it makes sense:
void someCallback(void *data)
{
(void)data; // <- this "uses" data
// [...] handler code that doesn't need data
}
Why is that? increasing variable not really using it.
Yes, it is really using it. At least from the language point of view. I would hope that an optimizer removes all trace of the variable.
Sure, that particular use has no effect on the rest of the program, so the variable is indeed redundant. I would agree that warning in this case would be helpful. But that is not the purpose of the warning about being unused, that you mention.
However, consider that analyzing whether a particular variable has any effect on the execution of the program in general is quite difficult. There has to be a point where the compiler stops checking whether a variable is actually useful. It appears that the stages that generate warnings of the compilers that you tested only check whether the variable is used at least once. That once was the increment operation.
I think there is a misconception about the word 'using' and what the compiler means with that. When you have a ++i you are not only accessing the variable, you are even modifying it, and AFAIK this counts as 'use'.
There are limitations to what the compiler can identify as 'how' variables are being used, and if the statements make any sense. In fact both clang and gcc will try to remove unnecessary statements, depending on the -O-flag (sometimes too aggressively). But these optimizations happen without warnings.
Detecting a variable that is never ever accessed or used though (there is no further statement mentioning that variable) is rather easy.
I agree with you, it could generate a warning about this. I think it doesn't generate a warning, because developers of the compilers just didn't bothered handling this case (yet). Maybe it is because it is too complicated to do. But maybe they will do this in the future (hint: you can suggest them this warning).
Compilers getting more and more warnings. For example, there is -Wunused-but-set-variable in GCC (which is a "new" warning, introduced in GCC 4.6 in 2011), which warns about this:
void fn() {
int a;
a = 2;
}
So it is completely fine to expect that this emits a warning too (there is nothing different here, neither codes do anything useful):
void fn() {
int a = 1;
a++;
}
Maybe they could add a new warning, like -Wmeaningless-variable
As per C standard ISO/IEC 9899:201x, expressions evaluation are always executed to allow for expression's side effects to be produced unless the compiler can't be sufficiently sure that removing it the program execution is not altered.
5.1.2.3 Program execution
In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).
When removing the line
++x;
The compiler can deduce that the local variable x is defined and initialized, but not used.
When you add it, the expression itself can be considered a void expression, that must be evaluated for side effects, as stated in:
6.8.3 Expression and null statements
The expression in an expression statement is evaluated as a void expression for its side effects.
On the other hand to remove compiler warnings relative to unused variable is very common to cast the expression to void. I.e. for an unused parameter in a function you can write:
int MyFunc(int unused)
{
(void)unused;
...
return a;
}
In this case we have a void expression that reference the symbol unused.

Need help regarding macro definition

Im reading c++ code, i have found such definition
#define USE_VAL(X) if (&X-1) {}
has anybody idea, what does it mean?
Based on the name, it looks like a way of getting rid of an "unused variable" warning. The intended use is probably something like this:
int function(int i)
{
USE_VAL(i)
return 42;
}
Without this, you could get a compiler warning that the parameter i is unused inside the function.
However, it's a rather dangerous way of going about this, because it introduces Undefined Behaviour into the code (pointer arithmetic beyond bounds of an actual array is Undefined by the standard). It is possible to add 1 to an address of an object, but not subtract 1. Of course, with + 1 instead of - 1, the compiler could then warn about "condition always true." It's possible that the optimiser will remove the entire if and the code will remain valid, but optimisers are getting better at exploiting "undefined behaviour cannot happen," which could actually mess up the code quite unexpectedly.
Not to mention that fact that operator& could be overloaded for the type involved, potentially leading to undesired side effects.
There are better ways of implementing such functionality, such as casting to void:
#define USE_VAL(X) static_cast<void>(X)
However, my personal preference is to comment out the name of the parameter in the function definition, like this:
int function(int /*i*/)
{
return 42;
}
The advantage of this is that it actually prevents you from accidentally using the parameter after passing it to the macro.
Typically it's to avoid an "unused return value" warning. Even if the usual "cast to void" idiom normally works for unused function parameters, gcc with -pedantic is particularly strict when ignoring the return values of functions such as fread (in general, functions marked with __attribute__((warn_unused_result))), so a "fake if" is often used to trick the compiler in thinking you are doing something with the return value.
A macro is a pre-processor directive, meaning that wherever it's used, it will be replaced by the relevant piece of code.
and here after USE_VAL(X) the space it is explain what will USE_VAL(X) do.
first it take the address of x and then subtract 1 from it. if it is 0 then do nothing.
where USE_VAL(X) will used it will replaced by the if (&X-1) {}

Reason behind using (void)someInt; in code

I am reading some code of a library I am using, and I found that in a function this was used:
void someFunction(Foo& a, int index, int partId)
{
(void) partId;
(void) index;
// more code
}
Anyone knows why? Thanks.
To avoid a compiler warning/error indicating that the variable was unused in the function body. It's a style choice, the other way to achieve the same effect would be to leave the variable un-named:
void someFunction(Foo& a, int /*index*/, int /*partId*/)
This is usually done when the parameters aren't being used in the function and the compiler emits a warning about unused parameters. By adding the case the compiler will deem that they have been used and not issue the waring.
You can accomplish the same thing my just removing the name of the parameter from the function:
void someFunction(Foo& a, int, int)
{
}
Index and partId are not used inside the function.
A C/C++ compiler will usually throw a warning about unused parameters.
the (void) parameter; statement will not generate any code, but let the compiler know you are using the parameter, in order to avoid the said warning.
It is also a polite way to let another programmer know easily that the parameters are unused for some reason
(typically, complying with a more generic interface or supporting obsolete parameters from a previous version of the same interface).
Last but not least, as Jerry Coffin pointed out, this works both in C and C++, while the alternative solution of using unnamed parameters only works in C++.
What it does is to use partId and index, without actually using them. In other words, it fools the compiler into thinking that the function arguments are actually used, while in reality the code doesn't use them.
Why would one do that? Because they have set a flag in the compiler to generate a warning when an argument of a function is not used in its body.
Note that in C++, one can simply remove the argument name from the function. If you see that in C, try disabling warning on unused function arguments since you can't omit argument names.

What does this define do?

What does this define do, and how would I use it?
#define UNUSED(VAR) (void)&(VAR)
Does it require a definition anywhere? This is in the header.
edit - I don't really understand what is going on here. is this a macro'd cast to void? doesn't that negate the variable?
It exists to avoid warnings for unused parameters and variables. Simply casting to void is enough for that: it uses the variable, and the cast usually does nothing. I can only guess what the & operator is used for here. Maybe it's to prevent a conversion operator from being called. However, it doesn't prevent an overloaded operator& from being called. Or it could be to make sure it is only used on variables, but that is not perfect either: it can be used on expressions that produce references.
The intention is to prevent yourself getting a compiler warning about an unused parameter.
The better way is just to leave it anonymous, e.g.
void do_stuff( int x, int );
the 2nd parameter is unused on this case. It may need to be there for some overload purpose.
With regards to using it for a local variable - you have to ask yourself, why declare a local variable and then not use it?
Well the answer may be that you use pre-processors in the code in such a way that a variable will sometimes be used but not always. However it may not always be practical to pre-process out its existence.
The fact you declare a variable unused does not make it an error if you really do use it.
It is a macro that can be used to stop the compiler complaining/warning about a variable that is delcared but not referenced. It is common to achieve the same result with a compiler #pragma setting to disable such warnings globaly.
It's for when you have you compiler produce warnings or errors if some variable remains unused. Using a define like this, you can insert a "no-op" that silences these warnings/errors if you checked the situation.
For example:
void foo()
{
int x=0;
UNUSED(x); // don't warn me that x is not actually being used
}

What are the consequences of ignoring: warning: unused parameter

I am working on a C++ project and I noticed that we have a number of warnings about unused parameters.
What effect could it have if these warnings are ignored?
The function with an unused parameter may have a real bug in the following cases:
There is an output parameter, which is not being assigned or written into, resulting in undefined value for the caller.
One of parameters is a callback function pointer, which you must invoke and forget to do so. May happen if there is a lot of #ifdefs in the function.
You declare a local variable with the same name that shadows a parameter and subsequently use the wrong value down in the function.
Not using an input parameters may be harmless, but you can reduce the noise to see useful warnings by marking unused input parameters explicitly in the beginning of the function by casting it to void (works for both C and C++):
(void)param1;
Or,
#define UNUSED(expr) do { (void)(expr); } while (0)
...
void foo(int param1, int param2)
{
UNUSED(param2);
bar(param1);
}
Or omit parameter name (C++ only):
void foo(int param1, int /*param2*/)
{
bar(param1);
}
If you have a whole lot of unimportant warnings that are not important to you, you may overlook the important warning about the line of code that you just wrote that is hiding in the middle of them.
For a gcc specific way to disable the warning, you can use __attribute__((unused)) like
void foo(int a, int b __attribute__((unused))) {
}
To ignore the second parameter. If your program relies on GCC technologies already, you can use that attribute to be 100% safe from that kind of warning.
It means you wrote a function that takes a parameter but doesn't use the parameter. It's harmless but it might indicate bugs in some cases.
Generally you can silence this warning by removing the parameter name, leaving it anonymous, but that may not be desirable depending on why the parameter is not being used.
I'd suggest you turn off the warning if it is making it harder to find the real problems.
In C++ you can have default arguments:
int sum(int first, int second=0){ // should not give warning
return first+first;
}
You can also have extra argument:
int sum(int first, int second){ // should give warning
first *= 2;
return first;
}
If you have a parameter you're not using and it's not defaulted, you should get a warning because you're asking the program to pass extra values to the stack that are never referenced, and therefore is doing more work than it should.
Maybe it means you forgot part of the function logic, too.
None. except [EDIT]: as others have pointed out, You could have an unassigned output parameter.
You should clean them up, because on many occasions I have seen developers ignore important warnings that were 'hidden' in amongst a large number of warnings, and they were so used to seeing warnings they never paid any attention to them. I try to have zero warnings at all times, and set compiler warnings to the maximum level.
That depends of if you intended to use the paramater. E.g.
const int Size = 12; // intended for use in some other function
char* MakeBuffer(int size)
{
return new char[Size];
}
In this code 'size' is unused, and instead the constant 'Size' is being used. So the warning will highlight problems of this type for you.
However, if you never indented to use the parameter then it should just be removed from the method signature. Unless you need to match a signature for a virtual method, or function pointer, if that's the case then you don't have the option to remove it.
If a method doesn't use a parameter then the first question that arises is that why is that parameter a part of the method's signature in the first place. These warnings do make sense since it is bad design that these are referring to and further, there is a little overhead as well that whenever this method is called, this parameter is pushed on the stack so, the best is to refactor the method and remove such parameters which do not have any use.
Having said that, leaving these parameters doesnt harm a lot except for a little overhead that I mentioned.