https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111897
--- Comment #3 from Agner Fog <agner at agner dot org> --- I have asked the authors of the linked document. They say that the example in the document is wrong. The latest version still has the error in the example: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html The compiler should give warnings for all of these: _Float16 A = 1.5; _Float16 B(1.5); _Float16 C{1.5}; but no warning for integers: _Float16 D = 2; It is fine to give a warning rather than an error message when the intention is obvious and there is no ambiguity. Below is my conversation with David Olsen: That’s correct. Conversions between integral and floating-point types are standard conversions, in both directions, which means they are implicit conversions. That was covered by preexisting wording in the standard, so P1467 doesn’t talk about those conversions. There isn’t a good way for the standard to clearly specify which conversions are lossless and which are potentially lossy, so we didn’t try to limit int/float conversions involving extended floating-point types to just the safe conversions. From: Agner Fog <ag...@agner.org> Sent: Tuesday, October 24, 2023 10:26 PM To: David Olsen <dol...@nvidia.com>; gri...@griwes.info Subject: Re: Problem with P1467R4 C++ std. proposal Thank you for a clear answer. I don't see any mentioning of implicit conversion from integer to extended floating point types. Is that allowed? gcc 13.1 gives no warning for implicit conversion from integer to float16: _Float16 A = 3; // no warning _Float16 A = 3.; // warning Is that correct? - Agner On 24/10/2023 19.29, David Olsen wrote: The final version of P1467 is R9, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html . The GCC 13 release notes contain a link to that version. Where do you see the link to R4? The issue of initialization of extended floating-point type variables was raised and discussed during the standardization process. R9 contains a long discussion of the issue, with some of the ways that we tried to fix the problem of initialization. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html#implicit-constant After some back and forth, the consensus was to leave the implicit conversion rules unchanged for initialization, because the potential solutions have their own problems. So all of _Float16 A = 1.5; _Float16 B(1.5); _Float16 C{1.5}; are ill-formed and should result in a compiler diagnostic. I am pleased that GCC reports only a warning and not a hard error, since the user's intent is obvious. Yes, the example in section 5.6.1 is wrong. The mistake is still there in R9 of the paper. It should be float f32 = 1.0f; std::float16_t f16 = 2.0f16; std::bfloat16_t b16 = 3.0bf16; On the more general issue of how much the new extended floating-point types should behave like the existing standard floating-point types, there was a long and useful discussion about this topic at a committee meeting in Feb 2020. There is general agreement that many of the defaults in C++ are wrong and can make it easier to write badly behaving code. Whenever new features are added, there is tension between the consistency of having them behave like existing features and the safety of choosing different defaults that makes it easier to write correct code. These competing goals and the consequences and tradeoffs of both of them were explicitly laid out and discussed at the Feb 2020 meeting, and at the end of the discussion there was strong consensus (though not unanimity) to go with safety over consistency for implicit conversions of extended floating-point types. int16_t is in the std namespace in C++. For C compatibility it is also available at global scope if you include <stdint.h> (defined by the C standard) instead of <cstdint> (defined by the C++ standard). The C++ standard doesn't define any names at global scope other than 'operator new' and 'operator delete'. Defining float16_t to be a global scope would have been a huge departure from existing practice. -----Original Message----- From: Agner Fog <ag...@agner.org> Sent: Tuesday, October 24, 2023 8:03 AM To: David Olsen <dol...@nvidia.com>; gri...@griwes.info Subject: Problem with P1467R4 C++ std. proposal Dear David Olsen and Michał Dominiak I don't know who to contact regarding C++ standard development, so I am taking the liberty to contact you as the authors of P1467R4, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1467r4.html#implicit It is unclear whether the rules for implicit conversion relate to initialization and assignment. gcc version 13.1 gives warnings for the following cases with reference to the above document: _Float16 A = 1.5; _Float16 B(1.5); _Float16 C{1.5}; The last one should probably not have a warning, the other ones are unclear. Initialization with an integer constant gives no warning message. The example in 5.6.1 in your document has: std::float16_t f16 = 2.0; Is this example wrong, or are there different rules for implicit conversion during initialization? In my opinion, it is a serious problem that the C++ language becomes so complicated and inconsistent that nobody can master it, apparently not even the people who write the standard. The only consistent rule would be that if implicit conversion between double and float is permitted, then implicit conversion between other floating point types should be permitted as well. The alleged problem that implicit conversion can lead to buggy code should be solved with compiler warnings, not error messages. Another inconsistency is that float16_t is in the std:: namespace, while int16_t is not. I think it is unnecessary to put float16_t and other new types in the std namespace because everything ending in "_t" is already considered reserved names. Adding std:: to everything makes the code kludgy. Best regards, and thank you for your work, Agner Fog, computer scientist, Technical University of Denmark