From a69c3247bf435683efbe059466857807a8de0fe2 Mon Sep 17 00:00:00 2001 From: Michael Winterberg Date: Wed, 19 May 2021 14:25:38 -0700 Subject: [PATCH 1/2] Avoid unwanted sign extensions from MSVC in is_utf8. Microsoft's constexpr evaluator treats the type of micro[0] and micro[1] as plain char, and so sign extends before comparing them to ints. The normal compiler, including the optimizer, does not fail in this way, so this is merely a "future proof" change in case someone uses is_utf8() in a constant expression. --- include/fmt/core.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 54927c06cef7..70c87d0ee55a 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -391,8 +391,11 @@ FMT_CONSTEXPR typename std::make_unsigned::type to_unsigned(Int value) { FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char micro[] = "\u00B5"; constexpr bool is_utf8() { - return FMT_UNICODE || - (sizeof(micro) == 3 && micro[0] == 0xC2 && micro[1] == 0xB5); + // avoid buggy sign extensions in MSVC's constant evaluation mode + // https://developercommunity.visualstudio.com/t/C-difference-in-behavior-for-unsigned/1233612 + using uchar = unsigned char; + return FMT_UNICODE || (sizeof(micro) == 3 && uchar{micro[0]} == 0xC2 && + uchar{micro[1]} == 0xB5); } FMT_END_DETAIL_NAMESPACE From df4b627fa6daa6b38a887c2d248fa8849f654df2 Mon Sep 17 00:00:00 2001 From: Michael Winterberg Date: Wed, 19 May 2021 15:14:30 -0700 Subject: [PATCH 2/2] addressing nits. --- include/fmt/core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 70c87d0ee55a..0882f8448fc9 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -391,11 +391,11 @@ FMT_CONSTEXPR typename std::make_unsigned::type to_unsigned(Int value) { FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char micro[] = "\u00B5"; constexpr bool is_utf8() { - // avoid buggy sign extensions in MSVC's constant evaluation mode + // Avoid buggy sign extensions in MSVC's constant evaluation mode. // https://developercommunity.visualstudio.com/t/C-difference-in-behavior-for-unsigned/1233612 using uchar = unsigned char; - return FMT_UNICODE || (sizeof(micro) == 3 && uchar{micro[0]} == 0xC2 && - uchar{micro[1]} == 0xB5); + return FMT_UNICODE || (sizeof(micro) == 3 && uchar(micro[0]) == 0xC2 && + uchar(micro[1]) == 0xB5); } FMT_END_DETAIL_NAMESPACE