From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 7BAD33858D28; Wed, 25 Oct 2023 07:40:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7BAD33858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1698219642; bh=hiGql6QoY3QB8XAW+TUHKhPeVaed2OkXgGSYrWppLm8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=baMKZaOnbLr+NqafWR9D0kauqMTyCXv0NFJHQ2qJItjMhGEqoidc1cpEiHuT6tVJ1 7sJSmvkbM2mhkAZ+wmW12PwdIT4S7lVrksdgi++6qto1/e56QOcIRE5bQIxAu6UUDe C2SYIHCrmD0OJta0ktf3FnTbMYZrnG0E0qiCfDVY= From: "agner at agner dot org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/111897] Initialization of _Float16 with f.p. constant gives false warning Date: Wed, 25 Oct 2023 07:40:41 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 13.1.0 X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: agner at agner dot org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D111897 --- Comment #3 from Agner Fog --- 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 exampl= e: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html The compiler should give warnings for all of these: _Float16 A =3D 1.5; _Float16 B(1.5); _Float16 C{1.5}; but no warning for integers: _Float16 D =3D 2; It is fine to give a warning rather than an error message when the intentio= n is obvious and there is no ambiguity. Below is my conversation with David Olsen: That=E2=80=99s correct. Conversions between integral and floating-point ty= pes are standard conversions, in both directions, which means they are implicit conversions. That was covered by preexisting wording in the standard, so P= 1467 doesn=E2=80=99t talk about those conversions. There isn=E2=80=99t a good w= ay for the standard to clearly specify which conversions are lossless and which are potentially lossy, so we didn=E2=80=99t try to limit int/float conversions involving ex= tended floating-point types to just the safe conversions. From: Agner Fog Sent: Tuesday, October 24, 2023 10:26 PM To: David Olsen ; griwes@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 =3D 3; // no warning _Float16 A =3D 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 w= as 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 pro= blem of initialization.=20 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html#impli= cit-constant After some back and forth, the consensus was to leave the implicit convers= ion rules unchanged for initialization, because the potential solutions have th= eir own problems. So all of _Float16 A =3D 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 inte= nt is obvious.=20=20=20=20=20 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 =3D 1.0f; std::float16_t f16 =3D 2.0f16; std::bfloat16_t b16 =3D 3.0bf16;=20=20=20=20=20 On the more general issue of how much the new extended floating-point t= ypes 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.= =20 There is general agreement that many of the defaults in C++ are wrong and c= an make it easier to write badly behaving code. Whenever new features are add= ed, 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 tradeof= fs of both of them were explicitly laid out and discussed at the Feb 2020 meet= ing, 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.=20=20=20=20=20 int16_t is in the std namespace in C++. For C compatibility it is also available at global scope if you include (defined by the C stand= ard) instead of (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 Sent: Tuesday, October 24, 2023 8:03 AM To: David Olsen ; griwes@griwes.info Subject: Problem with P1467R4 C++ std. proposal Dear David Olsen and Micha=C5=82 Dominiak=20=20=20=20=20 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, =20=20=20 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1467r4.html#impli= cit 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 =3D 1.5; _Float16 B(1.5); _Float16 C{1.5};=20=20=20=20=20 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 =3D 2.0; Is this example wrong, or are there different rules for implicit conver= sion 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 float= ing 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 ty= pes 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=