From be48f4d65792ce7526a34e4f1e9eb92d9e913b07 Mon Sep 17 00:00:00 2001 From: Michael Winterberg Date: Wed, 19 May 2021 14:25:38 -0700 Subject: [PATCH] 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 dc3db2e2..9875c3be 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -395,8 +395,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