From 12e310aa8f5a2a296a1d172e34aa30aadfaf2996 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Thu, 20 Aug 2026 13:30:32 -0400 Subject: [PATCH] Avoid old-style casts Replace C-style casts with static_cast/const_cast so -Wold-style-cast is clean, and enable that warning in the Unix test builds and the amalgamated-header CI job. --- .github/workflows/amalgamate-ubuntu24.yml | 2 +- benchmarks/bench_ip.cpp | 12 +++--- benchmarks/bench_uint16.cpp | 2 +- include/fast_float/ascii_number.h | 15 ++++---- include/fast_float/bigint.h | 4 +- include/fast_float/digit_comparison.h | 4 +- include/fast_float/float_common.h | 47 +++++++++++++---------- tests/CMakeLists.txt | 2 +- tests/basictest.cpp | 4 +- tests/exhaustive32_midpoint.cpp | 2 +- tests/string_test.cpp | 4 +- 11 files changed, 53 insertions(+), 45 deletions(-) diff --git a/.github/workflows/amalgamate-ubuntu24.yml b/.github/workflows/amalgamate-ubuntu24.yml index a7982d40..c2651fb1 100644 --- a/.github/workflows/amalgamate-ubuntu24.yml +++ b/.github/workflows/amalgamate-ubuntu24.yml @@ -14,4 +14,4 @@ jobs: python3 ./script/amalgamate.py > build/fast_float/fast_float.h && cp tests/string_test.cpp build/ && cd build && - g++ string_test.cpp + g++ -Werror=old-style-cast string_test.cpp diff --git a/benchmarks/bench_ip.cpp b/benchmarks/bench_ip.cpp index 825a6b0a..89e3a34f 100644 --- a/benchmarks/bench_ip.cpp +++ b/benchmarks/bench_ip.cpp @@ -108,10 +108,10 @@ int main() { buf.reserve(N * ip_size); for (size_t i = 0; i < N; ++i) { - uint8_t a = (uint8_t)dist(rng); - uint8_t b = (uint8_t)dist(rng); - uint8_t c = (uint8_t)dist(rng); - uint8_t d = (uint8_t)dist(rng); + uint8_t a = static_cast(dist(rng)); + uint8_t b = static_cast(dist(rng)); + uint8_t c = static_cast(dist(rng)); + uint8_t d = static_cast(dist(rng)); std::string ip_line = make_ip_line(a, b, c, d); ip_line.resize(ip_size, ' '); // pad to fixed size buf.append(ip_line); @@ -127,7 +127,7 @@ int main() { std::string buffer(ip_size * N, ' '); pretty_print(volume, bytes, "memcpy baseline", counters::bench([&]() { - std::memcpy((char *)buffer.data(), buf.data(), bytes); + std::memcpy(buffer.data(), buf.data(), bytes); })); pretty_print(volume, bytes, "just_seek_ip_end (no parse)", @@ -138,7 +138,7 @@ int main() { int ok = 0; for (size_t i = 0; i < N; ++i) { const char *q = seek_ip_end(p, pend); - sum += (uint32_t)(q - p); + sum += static_cast(q - p); p += ip_size; } sink += sum; diff --git a/benchmarks/bench_uint16.cpp b/benchmarks/bench_uint16.cpp index c4cef81b..a17db575 100644 --- a/benchmarks/bench_uint16.cpp +++ b/benchmarks/bench_uint16.cpp @@ -75,7 +75,7 @@ int main() { buffer.reserve(N * 6); // up to 5 digits + delimiter for (size_t i = 0; i < N; ++i) { - uint16_t val = (uint16_t)dist(rng); + uint16_t val = static_cast(dist(rng)); expected.push_back(val); std::string s = std::to_string(val); buffer.append(s); diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index 2748d65a..ba6983b8 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -32,7 +32,7 @@ template fastfloat_really_inline constexpr bool has_simd_opt() { // able to optimize it well. template fastfloat_really_inline constexpr bool is_integer(UC c) noexcept { - return (unsigned)(c - UC('0')) <= 9u; + return static_cast(c - UC('0')) <= 9u; } fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) { @@ -223,8 +223,8 @@ simd_parse_if_eight_digits_unrolled(char16_t const *chars, return false; FASTFLOAT_SIMD_RESTORE_WARNINGS #else - (void)chars; - (void)i; + static_cast(chars); + static_cast(i); return false; #endif // FASTFLOAT_SSE2 } @@ -601,7 +601,7 @@ parse_int_string(UC const *p, UC const *pend, T &value, FASTFLOAT_IF_CONSTEXPR17( (std::is_same::value && sizeof(UC) == 1)) { if (base == 10) { - const size_t len = (size_t)(pend - p); + const size_t len = static_cast(pend - p); if (len == 0) { if (has_leading_zeros) { value = 0; @@ -646,9 +646,10 @@ parse_int_string(UC const *p, UC const *pend, T &value, uint32_t magic = ((digits + 0x46464646u) | (digits - 0x30303030u)) & 0x80808080u; - uint32_t tz = (uint32_t)countr_zero_32(magic); // 7, 15, 23, 31, or 32 + uint32_t tz = + static_cast(countr_zero_32(magic)); // 7, 15, 23, 31, or 32 uint32_t nd = (tz == 32) ? 4 : (tz >> 3); - nd = (uint32_t)(nd < len ? nd : len); + nd = static_cast(nd < len ? nd : len); if (nd == 0) { if (has_leading_zeros) { value = 0; @@ -684,7 +685,7 @@ parse_int_string(UC const *p, UC const *pend, T &value, answer.ptr = p + nd; return answer; } - value = (uint8_t)((0x640a01 * digits) >> 24); + value = static_cast((0x640a01 * digits) >> 24); answer.ec = std::errc(); answer.ptr = p + nd; return answer; diff --git a/include/fast_float/bigint.h b/include/fast_float/bigint.h index 74901e39..665debb7 100644 --- a/include/fast_float/bigint.h +++ b/include/fast_float/bigint.h @@ -619,8 +619,8 @@ struct bigint : pow5_tables<> { // Work around clang bug https://godbolt.org/z/zedh7rrhc // This is similar to https://github.com/llvm/llvm-project/issues/47746, // except the workaround described there don't work here - FASTFLOAT_TRY(small_mul( - vec, limb(((void)small_power_of_5[0], small_power_of_5[exp])))); + FASTFLOAT_TRY(small_mul(vec, limb((static_cast(small_power_of_5[0]), + small_power_of_5[exp])))); } return true; diff --git a/include/fast_float/digit_comparison.h b/include/fast_float/digit_comparison.h index c2c83b0c..70085bed 100644 --- a/include/fast_float/digit_comparison.h +++ b/include/fast_float/digit_comparison.h @@ -400,8 +400,8 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp( round(answer, [ord](adjusted_mantissa &a, int32_t shift) { round_nearest_tie_even( a, shift, [ord](bool is_odd, bool _, bool __) -> bool { - (void)_; // not needed, since we've done our comparison - (void)__; // not needed, since we've done our comparison + static_cast(_); // not needed, since we've done our comparison + static_cast(__); // not needed, since we've done our comparison if (ord > 0) { return true; } else if (ord < 0) { diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index de39fdd8..2fc35496 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -225,12 +225,16 @@ using parse_options = parse_options_t; #ifndef FASTFLOAT_ASSERT #define FASTFLOAT_ASSERT(x) \ - { ((void)(x)); } + { \ + static_cast(x); \ + } #endif #ifndef FASTFLOAT_DEBUG_ASSERT #define FASTFLOAT_DEBUG_ASSERT(x) \ - { ((void)(x)); } + { \ + static_cast(x); \ + } #endif // rust style `try!()` macro, or `?` operator @@ -509,7 +513,7 @@ leading_zeroes(uint64_t input_num) { // Search the mask data from most significant bit (MSB) // to least significant bit (LSB) for a set bit (1). _BitScanReverse64(&leading_zero, input_num); - return (int)(63 - leading_zero); + return static_cast(63 - leading_zero); #else return leading_zeroes_generic(input_num); #endif @@ -556,7 +560,7 @@ countr_zero_32(uint32_t input_num) { #ifdef FASTFLOAT_VISUAL_STUDIO unsigned long trailing_zero = 0; if (_BitScanForward(&trailing_zero, input_num)) { - return (int)trailing_zero; + return static_cast(trailing_zero); } return 32; #else @@ -566,18 +570,21 @@ countr_zero_32(uint32_t input_num) { // slow emulation routine for 32-bit fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) { - return x * (uint64_t)y; + return x * static_cast(y); } fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) { - uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd); - uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd); - uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32)); - uint64_t adbc_carry = (uint64_t)(adbc < ad); + uint64_t ad = + emulu(static_cast(ab >> 32), static_cast(cd)); + uint64_t bd = emulu(static_cast(ab), static_cast(cd)); + uint64_t adbc = + ad + emulu(static_cast(ab), static_cast(cd >> 32)); + uint64_t adbc_carry = static_cast(adbc < ad); uint64_t lo = bd + (adbc << 32); - *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + - (adbc_carry << 32) + (uint64_t)(lo < bd); + *hi = + emulu(static_cast(ab >> 32), static_cast(cd >> 32)) + + (adbc >> 32) + (adbc_carry << 32) + static_cast(lo < bd); return lo; } @@ -612,7 +619,7 @@ full_multiplication(uint64_t a, uint64_t b) { !defined(_M_ARM64) && !defined(__GNUC__)) answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64 #elif defined(FASTFLOAT_64BIT) && defined(__SIZEOF_INT128__) - __uint128_t r = ((__uint128_t)a) * b; + __uint128_t r = static_cast<__uint128_t>(a) * b; answer.low = uint64_t(r); answer.high = uint64_t(r >> 64); #else @@ -874,7 +881,7 @@ template <> inline constexpr std::float16_t binary_format::exact_power_of_ten(int64_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)powers_of_ten[0], powers_of_ten[power]; + return static_cast(powers_of_ten[0]), powers_of_ten[power]; } template <> @@ -918,7 +925,7 @@ binary_format::max_mantissa_fast_path(int64_t power) { // power >= 0 && power <= 4 // // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)max_mantissa[0], max_mantissa[power]; + return static_cast(max_mantissa[0]), max_mantissa[power]; } template <> @@ -997,7 +1004,7 @@ template <> inline constexpr std::bfloat16_t binary_format::exact_power_of_ten(int64_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)powers_of_ten[0], powers_of_ten[power]; + return static_cast(powers_of_ten[0]), powers_of_ten[power]; } template <> @@ -1041,7 +1048,7 @@ binary_format::max_mantissa_fast_path(int64_t power) { // power >= 0 && power <= 3 // // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)max_mantissa[0], max_mantissa[power]; + return static_cast(max_mantissa[0]), max_mantissa[power]; } template <> @@ -1098,7 +1105,7 @@ binary_format::max_mantissa_fast_path(int64_t power) { // power >= 0 && power <= 22 // // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)max_mantissa[0], max_mantissa[power]; + return static_cast(max_mantissa[0]), max_mantissa[power]; } template <> @@ -1108,20 +1115,20 @@ binary_format::max_mantissa_fast_path(int64_t power) { // power >= 0 && power <= 10 // // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)max_mantissa[0], max_mantissa[power]; + return static_cast(max_mantissa[0]), max_mantissa[power]; } template <> inline constexpr double binary_format::exact_power_of_ten(int64_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)powers_of_ten[0], powers_of_ten[power]; + return static_cast(powers_of_ten[0]), powers_of_ten[power]; } template <> inline constexpr float binary_format::exact_power_of_ten(int64_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)powers_of_ten[0], powers_of_ten[power]; + return static_cast(powers_of_ten[0]), powers_of_ten[power]; } template <> inline constexpr int binary_format::largest_power_of_ten() { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 19f24529..f8cc1340 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -49,7 +49,7 @@ function(fast_float_add_cpp_test TEST_NAME) target_compile_options(${TEST_NAME} PUBLIC /EHsc) endif() if(NOT WIN32) - target_compile_options(${TEST_NAME} PUBLIC -Werror -Wall -Wextra -Weffc++) + target_compile_options(${TEST_NAME} PUBLIC -Werror -Wall -Wextra -Weffc++ -Wold-style-cast) target_compile_options(${TEST_NAME} PUBLIC -Wsign-compare -Wshadow -Wwrite-strings -Wpointer-arith -Winit-self -Wconversion -Wsign-conversion) endif() target_link_libraries(${TEST_NAME} PUBLIC fast_float supplemental-data) diff --git a/tests/basictest.cpp b/tests/basictest.cpp index dba36e8a..f9abefd6 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -1065,7 +1065,7 @@ void basic_test(float val) { do { \ constexpr int verify_comptime_var = \ (basic_test(__VA_ARGS__), 0); \ - (void)verify_comptime_var; \ + static_cast(verify_comptime_var); \ } while (false) #define verify_options_runtime(...) \ @@ -1077,7 +1077,7 @@ void basic_test(float val) { do { \ constexpr int verify_options_comptime_var = \ (basic_test(__VA_ARGS__, options), 0); \ - (void)verify_options_comptime_var; \ + static_cast(verify_options_comptime_var); \ } while (false) #if defined(FASTFLOAT_CONSTEXPR_TESTS) diff --git a/tests/exhaustive32_midpoint.cpp b/tests/exhaustive32_midpoint.cpp index d1fc1604..8feba7dc 100644 --- a/tests/exhaustive32_midpoint.cpp +++ b/tests/exhaustive32_midpoint.cpp @@ -61,7 +61,7 @@ template char *to_string(T d, char *buffer) { } void strtof_from_string(char const *st, float &d) { - char *pr = (char *)st; + char *pr = const_cast(st); #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || \ defined(sun) || defined(__sun) d = cygwin_strtof_l(st, &pr); diff --git a/tests/string_test.cpp b/tests/string_test.cpp index 69d2a31d..b0d3b20a 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -125,7 +125,7 @@ template bool test() { template void strtod_from_string(std::string const &st, T &d); template <> void strtod_from_string(std::string const &st, double &d) { - char *pr = (char *)st.c_str(); + char *pr = const_cast(st.c_str()); #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || \ defined(sun) || defined(__sun) d = cygwin_strtod_l(pr, &pr); @@ -142,7 +142,7 @@ template <> void strtod_from_string(std::string const &st, double &d) { } template <> void strtod_from_string(std::string const &st, float &d) { - char *pr = (char *)st.c_str(); + char *pr = const_cast(st.c_str()); #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || \ defined(sun) || defined(__sun) d = cygwin_strtof_l(st.c_str(), &pr);