C++: why this simple Scope Guard works?
Asked Answered
A

1

9

Every looked at scope guard so far has a guard boolean variable. For example, see this discussion: The simplest and neatest c++11 ScopeGuard

But a simple guard works (gcc 4.9, clang 3.6.0):

template <class C>
struct finally_t : public C {
    finally_t(C&& c): C(c) {}
    ~finally_t() { (*this)(); }
};
template <class C>
static finally_t<C> finally_create(C&& c) {
    return std::forward<C>(c);
}
#define FINCAT_(a, b) a ## b
#define FINCAT(a, b) FINCAT_(a, b)
#define FINALLY(...) auto FINCAT(FINALY_, __LINE__) = \
    finally_create([=](){ __VA_ARGS__ })

int main() {
    int a = 1;
    FINALLY( std::cout << "hello" << a << std::endl ; );
    FINALLY( std::cout << "world" << a << std::endl ; );
    return 0;
}

Why no temporary copies destructed? Is it dangerous to rely on this behavior?

Abbreviated answered 10/8, 2015 at 14:49 Comment(2)
You're observing the effects of Copy Elision (or Move Elision, in this case). Copy Elision is not guaranteed / mandatory, but usually performed by major compilers even when compiling w/o optimizations. Try gcc's -fno-elide-constructors to see it "break": melpon.org/wandbox/permlink/B73EuYYKGYFMnJtRWalkup
There is a trick to not rely on copy elision, few changes are required. Here is modification of your version which does not rely on copy elision.Brom
C
1

You're observing the effects of Copy Elision (or Move Elision, in this case). Copy Elision is not guaranteed / mandatory, but usually performed by major compilers even when compiling w/o optimizations. Try gcc's -fno-elide-constructors to see it "break": http://melpon.org/wandbox/permlink/B73EuYYKGYFMnJtR

Cleanser answered 10/8, 2015 at 14:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.