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.
Related
I have to use IAR compiller in embedded application (it does not have namespaces, exceptions, multiple/virtual inheritance, templates are bit limited and only C++03 is supported).
I can't use parameter pack so I tried to create member function with variadic parameter.
I know variadic parameters are generally unsafe. But is safe to use this pointer in va_start macro?
If I use ordinary variadic function it would need a dummy parameter before ... to be able to access remaining parameters. I know variadic macro would not need parameter before ... but I would prefer not to use it.
If I use member function it has hidden this parameter before ... so I tried it.:
struct VariadicTestBase{
virtual void DO(...)=0;
};
struct VariadicTest: public VariadicTestBase{
virtual void DO(...){
va_list args;
va_start(args, this);
vprintf("%d%d%d\n",args);
va_end(args);
}
};
//Now I can do
VariadicTestBase *tst = new VariadicTest;
tst->DO(1,2,3);
tst->DO(1,2,3); prints 123 as expected. But I am not sure if it is not just some random/undefined behavior. I know tst->DO(1,2); would crash just like normal prinf would. I do not mind it.
Nothing specifies that behaviour in the standard, so this construct just invokes formal Undefined Behaviour. That means that it can work fine in your implementation and cause compilation error or unexpected results in a different implementation.
The fact that non static methods have to pass the hidden this pointer cannot guarantee that va_start can use it. It probably works that way because in the early times, C++ compilers were just pre-processors that converted C++ source to C source and the hidden this parameter was added by the pre-processor to be available to the C compiler. And it has probably be maintained for compatibility reasons. But I would try hard to avoid that in mission critical code...
Seems to be undefined behavior. If you look at what va_start(ap, pN) does in many implementations (check your header file), it takes the address of pN, increments the pointer by the size of pN and stores the result in ap. Can we legally look at &this?
I found a nice reference here: https://stackoverflow.com/a/9115110/10316011
Quoting the 2003 C++ standard:
5.1 [expr.prim] The keyword this names a pointer to the object for which a nonstatic member function (9.3.2) is invoked. ... The type of the expression is a pointer to the function’s class (9.3.2), ... The expression is an rvalue.
5.3.1 [expr.unary.op] The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified_id.
So even if this works for you, it is not guaranteed to and you should not rely on it.
I think it should be OK, though I doubt you will find a specific citation from the C++ standard which says so.
The rationale is this: va_start() must be passed the last argument to the function. A member function taking no explicit parameters has only a single parameter (this), which therefore must be its last parameter.
It will be easy to add a unit test to alert you if you ever compile on a platform where this doesn't work (which seems unlikely, but then again you are already compiling on a somewhat atypical platform).
This is undefined behavior. Since the language does not require this to be passed as a parameter, it might not be passed at all.
For example, if a compiler can figure out that an object is a singleton, it may avoid passing this as a parameter and use a global symbol when the address of this is explicitly required (like in the case of va_start). In theory, the compiler might generate code to compensate that in va_start (after all, the compiler knows this is a singleton), but it is not required to do so by the standard.
Think of something like:
class single {
public:
single(const single& )= delete;
single &operator=(const single& )= delete;
static single & get() {
// this is the only place that can construct the object.
// this address is know not later than load time:
static single x;
return x;
}
void print(...) {
va_list args;
va_start (args, this);
vprintf ("%d\n", args);
va_end (args);
}
private:
single() = default;
};
Some compilers, like clang 8.0.0, emit a warning for the above code:
prog.cc:15:23: warning: second argument to 'va_start' is not the last named parameter [-Wvarargs] va_start (args, this);
Despite the warning, it runs ok. In general, this proves nothing, but it is a bad idea to have a warning .
Note: I don't know of any compiler that detects singletons and treats them specially, but the language does not forbid this kind of optimization. If it is not done today by your compiler, it might be done tomorrow by another compiler.
Note 2: despite all that, it might work in practice to pass this to va_start. Even if it works, it is not a good idea to do something that isn't guaranteed by the standard.
Note 3: The same singleton optimization can't be applied to parameters such as:
void foo(singleton * x, ...)
It can't be optimized away since it may have one of two values, point to the singleton or be nullptr. This means that this optimization concern does not apply here.
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.
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
}
I always thought that a function prototype must contain the parameters of the function and their names. However, I just tried this out:
int add(int,int);
int main()
{
std::cout << add(3,1) << std::endl;
}
int add(int x, int y)
{
return x + y;
}
And it worked! I even tried compiling with extreme over-caution:
g++ -W -Wall -Werror -pedantic test.cpp
And it still worked. So my question is, if you don't need parameter names in function prototypes, why is it so common to do so? Is there any purpose to this? Does it have something to do with the signature of the function?
No, these are not necessary, and are mostly ignored by the compiler. You can even give them different names in different declarations; the following is entirely legal:
int foo(int bar);
int foo(int biz);
int foo(int qux) {
...
}
(The compiler does check that each name is used only once in the same argument list: int foo(int bar, int bar); is rejected.)
The reason to put them in is documentation:
If someone reads your header file, they can tell at a glance what each parameter is used for.
If you use a fancy IDE, it can show you the parameter names when you begin typing the function call.
Documentation tools like Doxygen can parse the parameter names and show them in the documentation.
Parameter names are completely optional, and have no effect on compilation. They may be placed there for better readability of code.
You don't need parameter names in declarations. They are purely documentation.
You don't even need names in definitions:
int f(int)
{
return 0;
}
compiles just fine in C++ (though not in C). This is sometimes useful for e.g. inheritance, overloading, function pointers.
You do not need to include parameter names in function prototypes. You only need the complete signature, which includes the types of parameters and (in the case of function template specializations) return values.
However, it is still common to include parameter names in order to write self-documenting code. That is, a function with this declaration:
void foo(int number_of_foos_desired, string foo_replacement);
is easier to understand by looking only at the prototype, perhaps, than this one:
void foo(int, string);
Many modern IDEs will also pop up the parameter names as you type when you write code that calls this function. They may not be able to pop up this information if you dont include the parameter names in the prototype.
It has alot to do with the signature of the function.
One of the benefits of using .h files is that when someone comes along and wants to get a sense of what your program/api does, they can look at your header file and get a sense of what operations are being carried out, their inputs and outputs, how everything is going together, etc.
If you were to come across a method like
int doStuff(int,int)
this would be alot less telling than a method with a signature of say:
int doStuff(int firstNumberToAdd, int secondNumberToAdd);
with the second, you at least get some idea of the operations that are being carried out, and what is happening. This is the idea behind writing self documenting code.
If your interested, you may check out Code Complete by Steve McConnell.
There are different scenarios to it. I found it very helpful in dealing with inheritance and virtual functions. If you're using a virtual function that generates unused warning in sub class, you can omit the variable names.
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.