From 32bcaf61f52f604c7e268533b43f1ee0a61dff43 Mon Sep 17 00:00:00 2001 From: kwiberg Date: Thu, 27 Oct 2016 13:35:59 -0700 Subject: [PATCH] Improve RTC_DCHECK_op so that it won't trigger useless compiler warnings Before this change, with DCHECKs switched off, this sort of check size_t index = ...; RTC_DCHECK_GE(index, 0u); would cause GCC (but no other compiler that we use) to complain that unsigned values are always greater than or equal to 0. With this change, it no longer complains. (It was and remains the case that there was no complaints if DCHECKs were switched on, or if you used RTC_CHECK_op.) The reason for doing this change is that it isn't useful for the compiler to force us to remove DCHECKs just because their condition can be verified statically. That causes us to remove the checks, and once that's happened, future code changes are free to violate the removed checks and no one will know... BUG=webrtc:6620 Review-Url: https://codereview.webrtc.org/2455943002 Cr-Commit-Position: refs/heads/master@{#14805} --- webrtc/base/checks.h | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/webrtc/base/checks.h b/webrtc/base/checks.h index 2d0e8af5d2..aa6725dec7 100644 --- a/webrtc/base/checks.h +++ b/webrtc/base/checks.h @@ -83,16 +83,24 @@ namespace rtc { #define RTC_LAZY_STREAM(stream, condition) \ !(condition) ? static_cast(0) : rtc::FatalMessageVoidify() & (stream) -// The actual stream used isn't important. We reference condition in the code +// The actual stream used isn't important. We reference |ignored| in the code // but don't evaluate it; this is to avoid "unused variable" warnings (we do so // in a particularly convoluted way with an extra ?: because that appears to be // the simplest construct that keeps Visual Studio from complaining about // condition being unused). -#define RTC_EAT_STREAM_PARAMETERS(condition) \ - (true ? true : !(condition)) \ - ? static_cast(0) \ +#define RTC_EAT_STREAM_PARAMETERS(ignored) \ + (true ? true : ((void)(ignored), true)) \ + ? static_cast(0) \ : rtc::FatalMessageVoidify() & rtc::FatalMessage("", 0).stream() +// Call RTC_EAT_STREAM_PARAMETERS with an argument that fails to compile if +// values of the same types as |a| and |b| can't be compared with the given +// operation, and that would evaluate |a| and |b| if evaluated. +#define RTC_EAT_STREAM_PARAMETERS_OP(op, a, b) \ + RTC_EAT_STREAM_PARAMETERS(((void)sizeof(std::declval() \ + op std::declval()), \ + (void)(a), (void)(b))) + // RTC_CHECK dies with a fatal error if condition is not true. It is *not* // controlled by NDEBUG or anything else, so the check will be executed // regardless of compilation mode. @@ -193,12 +201,12 @@ DEFINE_RTC_CHECK_OP_IMPL(GT, > ) #define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2) #else #define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition) -#define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) == (v2)) -#define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) != (v2)) -#define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) <= (v2)) -#define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) < (v2)) -#define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) >= (v2)) -#define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS((v1) > (v2)) +#define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(==, v1, v2) +#define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(!=, v1, v2) +#define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(<=, v1, v2) +#define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(<, v1, v2) +#define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(>=, v1, v2) +#define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(>, v1, v2) #endif // This is identical to LogMessageVoidify but in name.