aboutsummaryrefslogtreecommitdiff
path: root/src/sync.h
diff options
context:
space:
mode:
authorCarl Dong <contact@carldong.me>2020-11-25 11:05:23 -0500
committerCarl Dong <contact@carldong.me>2020-12-04 12:23:05 -0500
commit3eb94ec81b72b14f72a1f6ce5c9aa24476df755a (patch)
tree9b3d0a79ffc34175ab71abf0e7325553d466ab87 /src/sync.h
parenta0489f3472f3799dc1ece32a59556fd239c4c14b (diff)
downloadbitcoin-3eb94ec81b72b14f72a1f6ce5c9aa24476df755a.tar.xz
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
Diffstat (limited to 'src/sync.h')
-rw-r--r--src/sync.h17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/sync.h b/src/sync.h
index 0948083c7f..faabec2c2d 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -256,7 +256,22 @@ using DebugLock = UniqueLock<typename std::remove_reference<typename std::remove
//!
//! int val = WITH_LOCK(cs, return shared_val);
//!
-#define WITH_LOCK(cs, code) [&] { LOCK(cs); code; }()
+//! Note:
+//!
+//! Since the return type deduction follows that of decltype(auto), while the
+//! deduced type of:
+//!
+//! WITH_LOCK(cs, return {int i = 1; return i;});
+//!
+//! is int, the deduced type of:
+//!
+//! WITH_LOCK(cs, return {int j = 1; return (j);});
+//!
+//! is &int, a reference to a local variable
+//!
+//! The above is detectable at compile-time with the -Wreturn-local-addr flag in
+//! gcc and the -Wreturn-stack-address flag in clang, both enabled by default.
+#define WITH_LOCK(cs, code) [&]() -> decltype(auto) { LOCK(cs); code; }()
class CSemaphore
{