This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4382. The simd::basic_mask(bool) overload needs to be more constrained

Section: 29.10.9.2 [simd.mask.ctor] Status: New Submitter: Matthias Kretz Opened: 2025-09-24 Last modified: 2025-09-26

Priority: Not Prioritized

View all issues with New status.

Discussion:

29.10.9.2 [simd.mask.ctor] defines the overloads basic_mask(bool) and basic_mask(unsigned_integral auto). This leads to the following pitfall:

auto g0() {
  unsigned short k = 0xf;
  return simd::mask<float, 8>(k); // mov eax, 15
}

auto g1() {
  unsigned short k = 0xf;
  return simd::mask<float, 8>(k >> 1); // mov eax, -1 ⚠️
}

auto g2() {
  unsigned int k = 0xf;
  return simd::mask<float, 8>(k >> 1); // mov eax, 7
}

In g1, k is promoted to int, shifted and then passed to the mask constructor. Instead of failing, int(0x7) is converted to bool and the mask thus initialized to all true.

Also consider:

  1. simd::mask<float>(true_type());

  2. unsigned_integral<bool> is true => same_as<bool> auto instead of 'bool' makes the overload set ambiguous

  3. float is convertible to bool, thus simd::mask<float>(1.f) continues to compile

Proposed resolution:

This wording is relative to N5014.

  1. Modify 29.10.9.1 [simd.mask.overview], class template basic_mask synopsis, as indicated:

    namespace std::simd {
      template<size_t Bytes, class Abi> class basic_mask {
      public:
        […]
        
        constexpr basic_mask() noexcept = default;
        
        // 29.10.9.2 [simd.mask.ctor], basic_mask constructors
        constexpr explicit basic_mask(value_type) noexcept;
        template<size_t UBytes, class UAbi>
          constexpr explicit basic_mask(const basic_mask<UBytes, UAbi>&) noexcept;
        template<class G>
          constexpr explicit basic_mask(G&& gen) noexcept;
        constexpr basic_mask(const bitset<size()>& b) noexcept;
        constexpr explicit basic_mask(unsigned_integral auto val) noexcept;
        basic_mask(signed_integral auto) = delete;
        
        […]
      };
    }