Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the compiler does not issue a warning when an object std::vector is declared but never used? [duplicate]

#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?

like image 624
Jovini Avatar asked Jun 20 '16 08:06

Jovini


People also ask

Which option can be used to display compiler warnings?

You can use a #pragma warning directive to control the level of warning that's reported at compile time in specific source files. Warning pragma directives in source code are unaffected by the /w option.

How does GCC treat warning errors?

The warning is emitted only with --coverage enabled. By default, this warning is enabled and is treated as an error. -Wno-coverage-invalid-line-number can be used to disable the warning or -Wno-error=coverage-invalid-line-number can be used to disable the error. Suppress warning messages emitted by #warning directives.

Which GCC flag is used to enable all compiler warning?

gcc -Wall enables all compiler's warning messages. This option should always be used, in order to generate better code.

Which flag would you pass to your C++ compiler so it warns you about implicit conversions?

By default, Fuchsia C/C++ code compiles with the flag -Wconversion , which prohibits implicit type conversions that may alter a value.


1 Answers

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.)

like image 55
Jonas Schäfer Avatar answered Sep 29 '22 19:09

Jonas Schäfer