Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#37 Improvement for ScopeGuard

open
nobody
None
5
2011-09-09
2011-09-09
Zenju
No

Hi,

short version:
I ask for a LOKI_ON_BLOCK_EXIT that does not emit a compiler warning about an unused variable on GCC and MSVC.

long version:
one use of ScopeGuard is as a convenient RAII "cleanup" mechanism, that is without calling "Dismiss()" later.
The problem then is that GCC and MSVC emit compiler warnings about an unused variable.
This happens both when using a dummy variable without dismissing it and more critically when using "LOKI_ON_BLOCK_EXIT", which is specifically designed for that purpose.

As seen here, others have been looking for an answer, but with little success:
http://stackoverflow.com/questions/219770/dealing-with-c-initialized-but-not-referenced-warning-for-destruction-of-scop

For GCC, there is a nice and simple solution which could be implemented by the Loki library:
replace:
typedef const ScopeGuardImplBase& ScopeGuard;
by
__attribute__((unused)) typedef const ScopeGuardImplBase& ScopeGuard;

Unfortunately there is no MSVC equivalent.

Now with C++11, there might be light at the end of the tunnel:
One way to silence the warning about unused variable in both GCC and MSVC is to get rid of the const-reference:
typedef const ScopeGuardImplBase& ScopeGuard; -> typedef ScopeGuardImplBase ScopeGuard;
It's clear that this creates problems for the general ScopeGuard case where the type is dependent from the number and types of arguments passed. But for LOKI_ON_BLOCK_EXIT, this shouldn't matter. What's still missing is a way to "pass the value without copying". Here C++11 r-value-refences are the fitting solution.

You see, there are a few open questions, but my hope is that they can be figured out eventually.

Best regards, ZenJu

Discussion

  • Zenju
    Zenju
    2011-09-09

    > typedef const ScopeGuardImplBase& ScopeGuard; -> typedef ScopeGuardImplBase ScopeGuard;
    The example is wrong, but the main idea is to get rid of the reference and move to a value type.

     
  • Zenju
    Zenju
    2011-09-22

    Hi,

    here is an actually working proposal for C++11: It's some more steroids for LOKI_ON_BLOCK_EXIT:

    #define LOKI_ON_BLOCK_EXIT2(X) ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeGuard([&](){X;}); (void)LOKI_ANONYMOUS_VARIABLE(scopeGuard);

    Resulting Syntax:

    LOKI_ON_BLOCK_EXIT2(::CloseHandle(hDir));

    Multiple statements are possible also:
    LOKI_ON_BLOCK_EXIT2(::CloseHandle(hDir);
    ::CloseHandle(hDir));

    And most importantly: no warning about unused variable anymore, both GCC and MSVC10!
    Personally, I like the syntax a lot more than BOOST_SCOPE_EXIT (not to mention the bunch of header dependencies), so I would love to see something like this in Loki!

    Regards, ZenJu