Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with C++ "initialized but not referenced" warning for destruction of scope helpers?

In Visual Studio, I often use objects only for RAII purposes. For example:

ScopeGuard close_guard = MakeGuard( &close_file, file );

The whole purpose of close_guard is to make sure that the file will be close on function exit, it is not used anywhere else. However, Visual Studio gives me a warning that a "local variable is initialized but not referenced". I want to turn this warning off for this specific case.

How do you deal with this kind of situation? Visual Studio thinks that this object is useless, but this is wrong since it has a non-trivial destructor.

I wouldn't want to use a #pragma warning directive for this since it would turn off this warning even for legitimate reasons.

like image 987
Martin Cote Avatar asked Oct 20 '08 20:10

Martin Cote


3 Answers

If your object has a non-trivial destructor, Visual Studio should not be giving you that warning. The following code does not generate any warnings in VS2005 with warnings turned all the way up (/W4):


class Test
{
public:
    ~Test(void) { printf("destructor\n"); }
};

Test foo(void) { return Test(); }

int main(void)
{
    Test t = foo();
    printf("moo\n");

    return 0;
}

Commenting out the destructor gives a warning; the code as-is does not.

like image 71
Adam Rosenfield Avatar answered Oct 17 '22 11:10

Adam Rosenfield


Method 1: Use the #pragma warning directive.

#pragma warning allows selective modification of the behavior of compiler warning messages.

#pragma warning( push )
#pragma warning( disable : 4705 ) // replace 4705 with warning number

ScopeGuard close_guard = MakeGuard( &close_file, file );

#pragma warning( pop )

This code saves the current warning state, then it disables the warning for a specific warning code and then restores the last saved warning state.

Method 2: Use a workaround like the following. Visual Studio will be happy and so will you. This workaround is used in many Microsoft samples and also in other projects.

ScopeGuard close_guard = MakeGuard( &close_file, file );
close_guard;

Or you can create a #define to workaround the warning.

#define UNUSED_VAR(VAR) VAR
...
ScopeGuard close_guard = MakeGuard( &close_file, file );
UNUSED_VAR(close_guard);

Some users stated that the code presented will not work because ScopeGuard is a typedef. This assumption is wrong.

http://www.ddj.com/cpp/184403758

According to the C++ Standard, a reference initialized with a temporary value makes that temporary value live for the lifetime of the reference itself.

like image 6
7 revs Avatar answered Oct 17 '22 13:10

7 revs


We use:

static_cast<void>(close_guard);

for variables that the compiler is complaining about.

like image 3
Douglas Leeder Avatar answered Oct 17 '22 11:10

Douglas Leeder