Repository navigation
CWG3036 [basic.extended.fp] std::float16_t may be an alias for a const type #710
Description
Activity
I wonder whether it's clearer to just say
using float16_t = decltype(0.0f16);in the library wording, as [expr.prim.literal] p1 ensures that the type is cv-unqualified.
But the library wording currently says implementation-defined, and simply changing todecltype(0.0f16)will drop the entry in the implementation-defined behavior list. I don't know what should be documented for the implementation-defined choice here, at all.I think
using float16_t = decltype(0f16)would be an improvement, but currently it would be a normative change due to this core issue. The type of these literals is defined to be one of the type aliases in the library, not the other way around.Once that is resolved, it would be nice, and it would be consistent with
using nullptr_t = decltype(nullptr);
- Reacted by Jan Schultke and A. Jiang
- changed the title
[-][basic.extended.fp] `std::float16_t` may be an alias for a `const` type[/-][+]CWG3036 [basic.extended.fp] `std::float16_t` may be an alias for a `const` type[/+]on Jul 26, 2025 I thought
using float32_t = decltype(0.0f32);
would result in a circular definition, but it looks fine actually.
- https://eel.is/c++draft/basic.extended.fp#2 states that
float32_tnames "such a type", so the definition is narrowed down to a cv extended floating-point type with certain properties. - https://eel.is/c++draft/stdfloat.syn with CWG3036's
decltype(literal)would additionally narrow it down to a cv-unqualifiedf32-typed thing because literals are prvalues, and https://eel.is/c++draft/expr.type#2 states that cv prvalues are adjusted to cv-unqualified prvalues in this case - https://eel.is/c++draft/tab:lex.fcon.type then states that
f32literals are of typestd::float32_t, tying it all together
I don't like the indirect nature of this; it takes four subclauses to collectively define what
float32_tis. However I doubt anyone else is seriously bothered. It technically works.- https://eel.is/c++draft/basic.extended.fp#2 states that
Given that new definition of
std::float16_t, do you have a suggestion for the core language wording that maybe makes it more nullptr_t-like and thus less .. circular-ish?If we added "cv-unqualified" as in/similar to the original suggested resolution, then [basic.extended.fp] would fully define what type
std::float16_tis. [stdfloat.syn] and [tab:lex.fcon.type] would still be a bit circular, butfloat16_tis already fully defined prior to these subclauses, so they wouldn't be load-bearing.Another way to break the cycle is to say in [basic.extended.fp] that the type of the
f16literals is the type mentioned within that paragraph, not just thatf16is "supported".Either approach would be an improvement in my opinion; I don't see any other obvious way to make it less circular, and defining
float32_tasdecltype(0.0f16), andf16asfloat16_tlooks editorially elegant when looking at these definitions individually.
Reference (section label): [basic.extended.fp]
Issue description
"Extended floating-point types" ([basic.fundamental]) includes cv-qualified types, and it is not clearly specified that
std::float16_tand other type aliases shall name cv-unqualified types becausestd::float16_tis simply stated to "name such [an extended floating-point] type".Suggested resolution
Change [basic.extended.fp] paragraph 1 as follows:
If the implementation supports an extended floating-point type ([basic.fundamental]) whose properties are specified by the ISO/IEC 60559 floating-point interchange format binary16, then the typedef-name std::float16_t is declared in the header <stdfloat> and names such a +cv-unqualified ([basic.type.qualifier]) type, the macro __STDCPP_FLOAT16_T__ is defined ([cpp.predefined]), and the floating-point literal suffixes f16 and F16 are supported ([lex.fcon]).Change paragraphs 2, 3, 4, and 5 analogously.