Skip to content

<compare>: ordering types are default constructible and constructible from integer types #5689

@leni536

Description

@leni536

Describe the bug

As implemented in MS STL, ordering types in are default constructible and constructible from integer types.

test case

#include <compare>
#include <type_traits>

static_assert(std::is_default_constructible_v<std::strong_ordering>);
static_assert(std::is_constructible_v<std::strong_ordering, int>);

auto s1 = std::strong_ordering();
auto s2 = std::strong_ordering(42);;

https://godbolt.org/z/37oEMvxj8

Expected behavior

As specified in the standard, these constructions are not required to work, or required to not work, depending on the reading of [member.functions]/2 and the resolution of the recent [LWG4306].

Regardless of the resolution, allowing these constructions is undesirable, at least because the behavior diverges from other implementations which enables users to accidentally write non-portable code.

STL version

From the above godbolt link: x64 msvc v19.43 VS17.13

Possible resolution

Making the defaulted default constructor of the ordering types private could resolve this without requiring an ABI break, like so:

class ordering {
  private:
  ordering()  = default;
  public:
  signed char value;
};

These ordering types are passed around in registers for parameters and for return. MSVC seems to require the type to satisfy C++14's definition of aggregate to pass it in register when returning it from a function. Making the default constructor explicitly defaulted and private still satisfies this definition, and the ordering type could still be returned in a register.

In turn it makes the type non-aggregate from C++20 onward (which is when the types are introduced to begin with), so it's not default constructible, not constructible from {}, and not constructible from integer types.

Additional context

isocpp-lib reflector thread: https://lists.isocpp.org/lib/2025/07/32342.php

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementSomething can be improved

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions