Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::ignore for ignoring unused variable

Is it a good approach to use std::ignore for ignoring unused variables?

Suppose I have a function like this:

void func(int i) {    //for some reason, I don't need i anymore but I cannot change signature of function        std::ignore = i;  } 

Additional Info

This was one example and some answers suggested to use anonymous variables. But how would I do it for other cases, like:

int Thread_UnSafe_func_returnSomething(): void func() {    // To make it thread safe    // Also it is required to call only once    static int i = Thread_UnSafe_func_returnSomething();     std::ignore = i; } 
like image 529
gaurav bharadwaj Avatar asked Sep 28 '16 11:09

gaurav bharadwaj


People also ask

How do I ignore unused variable warning?

By default, the compiler does not warn about unused variables. Use -Wunused-variable to enable this warning specifically, or use an encompassing -W value such as -Weverything . The __attribute__((unused)) attribute can be used to warn about most unused variables, but suppress warnings for a specific set of variables.

What is STD ignore?

std::ignoreAn object of unspecified type such that any value can be assigned to it with no effect. Intended for use with std::tie when unpacking a std::tuple, as a placeholder for the arguments that are not used.

What are unused variables?

Unused variables are a waste of space in the source; a decent compiler won't create them in the object file. Unused parameters when the functions have to meet an externally imposed interface are a different problem; they can't be avoided as easily because to remove them would be to change the interface.

What is unused parameter?

Reports the parameters that are considered unused in the following cases: The parameter is passed by value, and the value is not used anywhere or is overwritten immediately. The parameter is passed by reference, and the reference is not used anywhere or is overwritten immediately.


2 Answers

std::ignore may work but it is intended to be used for tuples. So you need to include the tuple header and who knows what operations are done for the assignment. This also may break in another c++ version because it was never documented to be used that way.

A better way for this is the C++17 attribute [[maybe_unused]]

void func([[maybe_unused]] int i) { } 

It places the declaration right at the variable declaration, so you don't have to declare it in an extra line/statement.

The same can be used for local (and local-static) variables

... [[maybe_unused]] static int a = something(); ... 

And also for many more:

Appears in the declaration of a class, a typedef­, a variable, a non­static data member, a function, an enumeration, or an enumerator. If the compiler issues warnings on unused entities, that warning is suppressed for any entity declared maybe_unused.

See http://en.cppreference.com/w/cpp/language/attributes

As for the people concerned that you can still use the variables after you declare them unused:

Yes, this is possible but (at least with clang) you will get warnings in case you use maybe_unused declared variables.

like image 191
Hayt Avatar answered Sep 18 '22 18:09

Hayt


In such case just don't write variable name:

void func(int /*i*/) {     ... } 

@Hayt's answer is good, but uses latest version of C++ which is not always available. Not writing variable name is an old convention to tell a compiler that you don't actually need the variable.

For an updated question I would go for a static instance of a class with needed initialization in a constructor. I say initialization because the only reason I can make for having such function is to initialize some global object.

class SomethingInitializer { public:     SomethingInitializer() {         func_returnSomething();     }     ~SomethingInitializer() {         // Note, that when you initialize something it is a good practice to deinitialize it at the end, and here is a proper place for that.     } };  void func() {     static SomethingInitializer initializer; } 

This solution has a small bonus: SomethingInitializer is RAII compliant. So when application terminates destructor is called and it can make deinitialization.

Note, that compiler knows that classes may do something useful in constructor and destructor, so it will not complain for unused variable.

like image 29
Alexey Guseynov Avatar answered Sep 20 '22 18:09

Alexey Guseynov