From 0975620aefc02b46d2c888948c7382ebd3884e47 Mon Sep 17 00:00:00 2001 From: "Hans J. Johnson" Date: Tue, 16 Jun 2026 09:05:04 -0500 Subject: [PATCH] COMP: Guard vnl_math integral predicates from MSVC fpclassify The VXL 2026-06-09 sync routes vnl_matrix::is_finite()/has_nans() through numeric_predicates::isfinite/isnan, which forward std::isfinite for every T. For integral T this hits the Windows UCRT integer template, where fpclassify() is ambiguous (C2668) on MSVC 14.38 + SDK 10.0.22621/22000; every integer-typed vnl_matrix and vnl_vector TU fails to compile. CI (MSVC 14.44) is unaffected. Short-circuit integral arguments with `if constexpr`: an integer is always finite, never inf/NaN, normal when non-zero. ITK-local patch pending an upstream VXL fix. --- .../VNL/src/vxl/core/vnl/vnl_math.h | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/Modules/ThirdParty/VNL/src/vxl/core/vnl/vnl_math.h b/Modules/ThirdParty/VNL/src/vxl/core/vnl/vnl_math.h index 4c9d87b1bdd..296278a3028 100644 --- a/Modules/ThirdParty/VNL/src/vxl/core/vnl/vnl_math.h +++ b/Modules/ThirdParty/VNL/src/vxl/core/vnl/vnl_math.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #ifdef _MSC_VER # include @@ -179,29 +180,54 @@ namespace numeric_predicates { // Wrap the classification functions to guarantee a bool return type; // some standard libraries returned a signed integer from these. +// Integral arguments are short-circuited: an integer is always finite, never +// inf/NaN, and normal when non-zero. This also avoids an ambiguous fpclassify +// overload in older Windows SDK integer templates. +// ITK-local patch (not yet upstream in VXL): the `if constexpr` integral +// branches below; remove if a future VXL sync fixes this upstream. template inline bool isinf(TArg arg) { - return bool(std::isinf(arg)); + // Integral branch: works around an ambiguous fpclassify overload in old + // Windows SDK ; an integer is never inf. + if constexpr (std::is_integral_v) + return false; + else + return bool(std::isinf(arg)); } template inline bool isnan(TArg arg) { - return bool(std::isnan(arg)); + // Integral branch: works around an ambiguous fpclassify overload in old + // Windows SDK ; an integer is never NaN. + if constexpr (std::is_integral_v) + return false; + else + return bool(std::isnan(arg)); } template inline bool isfinite(TArg arg) { - return bool(std::isfinite(arg)); + // Integral branch: works around an ambiguous fpclassify overload in old + // Windows SDK ; an integer is always finite. + if constexpr (std::is_integral_v) + return true; + else + return bool(std::isfinite(arg)); } template inline bool isnormal(TArg arg) { - return bool(std::isnormal(arg)); + // Integral branch: works around an ambiguous fpclassify overload in old + // Windows SDK ; a non-zero integer is normal. + if constexpr (std::is_integral_v) + return arg != TArg(0); + else + return bool(std::isnormal(arg)); } } // namespace numeric_predicates