From fa38102109de23644e05a1c09e48110bd043a7b2 Mon Sep 17 00:00:00 2001 From: devtejasx Date: Thu, 23 Jul 2026 22:28:29 +0530 Subject: [PATCH] Replace offsetof cache-line check with a well-defined runtime check (#1877) The static_assert used offsetof(State, skipped_) to verify that commonly accessed data stays on the first cache line. State is not a standard-layout type (it has non-static data members with differing access control), so offsetof() on it is undefined behavior and is diagnosed by -Winvalid-offsetof on clang (and equivalents elsewhere). This forced a stack of compiler-specific pragmas (GCC/Clang, ICC, NVCC, NVHPC) just to silence the warning, and it still broke -Werror builds on newer clang. Compute the offset from the live object instead (address of the member minus address of the object), which is well defined. The check now runs at construction time via BM_CHECK, so it is active in debug/CI builds and is a no-op under NDEBUG. This removes all the offsetof-suppression pragmas. AI-assisted: patch drafted with AI assistance (Claude); reviewed, tested, and understood by me. I take full responsibility for it. --- src/benchmark.cc | 49 +++++++++++++----------------------------------- 1 file changed, 13 insertions(+), 36 deletions(-) diff --git a/src/benchmark.cc b/src/benchmark.cc index 91280295e..c39307d00 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -222,42 +222,19 @@ State::State(std::string name, IterationCount max_iters, } } - // Note: The use of offsetof below is technically undefined until C++17 - // because State is not a standard layout type. However, all compilers - // currently provide well-defined behavior as an extension (which is - // demonstrated since constexpr evaluation must diagnose all undefined - // behavior). However, GCC and Clang also warn about this use of offsetof, - // which must be suppressed. -#if defined(__INTEL_COMPILER) -#pragma warning push -#pragma warning(disable : 1875) -#elif defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Winvalid-offsetof" -#endif -#if defined(__NVCC__) -#pragma nv_diagnostic push -#pragma nv_diag_suppress 1427 -#endif -#if defined(__NVCOMPILER) -#pragma diagnostic push -#pragma diag_suppress offset_in_non_POD_nonstandard -#endif - // Offset tests to ensure commonly accessed data is on the first cache line. - const int cache_line_size = 64; - static_assert( - offsetof(State, skipped_) <= (cache_line_size - sizeof(skipped_)), ""); -#if defined(__INTEL_COMPILER) -#pragma warning pop -#elif defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic pop -#endif -#if defined(__NVCC__) -#pragma nv_diagnostic pop -#endif -#if defined(__NVCOMPILER) -#pragma diagnostic pop -#endif + // Ensure commonly accessed data is on the first cache line. + // + // We deliberately avoid offsetof() here: State is not a standard-layout type + // (it has non-static data members with differing access control), so + // offsetof() on it is undefined behavior and is diagnosed by + // -Winvalid-offsetof (and equivalents on other compilers), which previously + // had to be suppressed with a stack of compiler-specific pragmas. Instead we + // compute the offset from the live object, which is well defined. This runs + // only in debug builds, as BM_CHECK is a no-op under NDEBUG. + BM_CHECK_LE(reinterpret_cast(&skipped_) - + reinterpret_cast(this), + /*cache_line_size=*/64 - + static_cast(sizeof(skipped_))); } void State::PauseTiming() {