Skip to content

Commit 3eb94ec

Browse files
committed
sync: Use decltype(auto) return type for WITH_LOCK
Now that we're using C++17, we can use the decltype(auto) return type (available since C++14) for functions and lambda expressions. As demonstrated in this commit, this can simplify cases where previously the compiler failed to deduce the correct return type. Just for reference, for the "assign to ref" cases fixed here, there are 3 possible solutions: - Return a pointer and immediately deref as used before this commit - Make sure the function/lambda returns declspec(auto) as used after this commit - Class& i = WITH_LOCK(..., return std::ref(...)); ----- References: 1. https://en.cppreference.com/w/cpp/language/function#Return_type_deduction 2. https://en.cppreference.com/w/cpp/language/template_argument_deduction#Other_contexts 3. https://en.cppreference.com/w/cpp/language/auto 4. https://en.cppreference.com/w/cpp/language/decltype Explanations: 1. https://stackoverflow.com/a/21369192 2. https://stackoverflow.com/a/21369170 3. Item 3 in Effective Modern C++ (Scott Meyers) via jnewbery
1 parent a0489f3 commit 3eb94ec

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

src/sync.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,22 @@ using DebugLock = UniqueLock<typename std::remove_reference<typename std::remove
256256
//!
257257
//! int val = WITH_LOCK(cs, return shared_val);
258258
//!
259-
#define WITH_LOCK(cs, code) [&] { LOCK(cs); code; }()
259+
//! Note:
260+
//!
261+
//! Since the return type deduction follows that of decltype(auto), while the
262+
//! deduced type of:
263+
//!
264+
//! WITH_LOCK(cs, return {int i = 1; return i;});
265+
//!
266+
//! is int, the deduced type of:
267+
//!
268+
//! WITH_LOCK(cs, return {int j = 1; return (j);});
269+
//!
270+
//! is &int, a reference to a local variable
271+
//!
272+
//! The above is detectable at compile-time with the -Wreturn-local-addr flag in
273+
//! gcc and the -Wreturn-stack-address flag in clang, both enabled by default.
274+
#define WITH_LOCK(cs, code) [&]() -> decltype(auto) { LOCK(cs); code; }()
260275

261276
class CSemaphore
262277
{

src/test/validation_chainstate_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
3535
return outp;
3636
};
3737

38-
CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(mempool));
38+
CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(mempool));
3939
c1.InitCoinsDB(
4040
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
4141
WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));

src/test/validation_chainstatemanager_tests.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
2929

3030
// Create a legacy (IBD) chainstate.
3131
//
32-
CChainState& c1 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(mempool));
32+
CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(mempool));
3333
chainstates.push_back(&c1);
3434
c1.InitCoinsDB(
3535
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
@@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
5555

5656
// Create a snapshot-based chainstate.
5757
//
58-
CChainState& c2 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(mempool, GetRandHash()));
58+
CChainState& c2 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(mempool, GetRandHash()));
5959
chainstates.push_back(&c2);
6060
c2.InitCoinsDB(
6161
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
@@ -114,7 +114,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
114114

115115
// Create a legacy (IBD) chainstate.
116116
//
117-
CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(mempool));
117+
CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(mempool));
118118
chainstates.push_back(&c1);
119119
c1.InitCoinsDB(
120120
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
@@ -131,7 +131,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
131131

132132
// Create a snapshot-based chainstate.
133133
//
134-
CChainState& c2 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(mempool, GetRandHash()));
134+
CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(mempool, GetRandHash()));
135135
chainstates.push_back(&c2);
136136
c2.InitCoinsDB(
137137
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);

0 commit comments

Comments
 (0)