Why the compiler does not issue a warning when an

2019-03-17 22:50发布

This question already has an answer here:

#include <vector>

class Object
{
};

int main()
{
    Object myObject;
    std::vector<int> myVector;
}

Compiler emits:

warning: unused variable 'myObject' [-Wunused-variable]

No warning for myVector. Why? Is there any way to enable this?

3条回答
等我变得足够好
2楼-- · 2019-03-17 23:18

Whether declaring (and thus initialising and at some point destructung) an arbitrary object has visible side effects cannot be determined in general. The constructor may be calling functions whose definition is not known to the compiler or it may depend on external state or any other aspect which makes the problem undecidable.

In your first case, the constructor is trivial (not even declared), same for the destructor. As Object does not have members, it is clear and easily detectable that Object foo does in fact nothing.

std::vector has a non-trivial constructor which may be allocating memory (external state + function whose definition may not be known (new ...)) together with a non-trivial destructor (also external state + function whose definition may not be known (delete ...)). Reasoning about whether it is safe to remove the declaration (thus emitting a warning hinting that you maybe should) is not possible in this case, thus the compiler has to leave the declaration in the code (and must assume that the declaration is there for a reason).

A prime example is std::lock_guard which is used to lock a mutex when it is constructed and unlock it automatically when it is destructed. The mutex is thus held as long as the object is in scope; generally you would not access the std::lock_guard object at all though—nevertheless it is useful to have it declared. This is the RAII principle at work.

Emitting a warning in such cases would be a nuisance, leading to people turning off the warning, which in turn would render the warning useless. (The compiler may even be designed in such a way that it only emits the warning if it has removed the declaration during optimisation, which is also the reason why some warnings only show up if certain optimisations are enabled.)

查看更多
SAY GOODBYE
3楼-- · 2019-03-17 23:22

This warning is generated only for trivial types. Compiler is not able to find whether construct will call any external function. If you add a constructor to your Object class then compiler will also issue a warning. Gcc allows to tag types which should generate this warning, you can do this using __attribute__((warn_unused)) :

http://coliru.stacked-crooked.com/a/0130c8ef29c121a1

example:

class __attribute__((warn_unused)) Object
{
    public:
    Object(){}
    void use() {}
};

int main()
{
    Object myObject;  // will give : warning: unused variable 'myObject' [-Wunused-variable]
    //myObject.use(); // uncomment to hide this warning
}

[edit]

from gcc attributes page: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html :

warn_unused For C++ types with non-trivial constructors and/or destructors it is impossible for the compiler to determine whether a variable of this type is truly unused if it is not referenced. This type attribute informs the compiler that variables of this type should be warned about if they appear to be unused, just like variables of fundamental types. This attribute is appropriate for types which just represent a value, such as std::string; it is not appropriate for types which control a resource, such as std::lock_guard.

This attribute is also accepted in C, but it is unnecessary because C does not have constructors or destructors.

查看更多
ら.Afraid
4楼-- · 2019-03-17 23:28

As well as the answers above, also check your compiler documentation. Some compilers can be set so that they do not show the same warning multiple times. If you comment out the declaration of "myObject", you may then get the same warning for "myVector". With "mObject" producing that warning first, you wouldn't get a warning for "myVector".

Compiler behaviour in the case of warnings is very compiler-specific, so don't assume that all compilers work the same. :)

查看更多
登录 后发表回答