public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/111897] New: Initialization of _Float16 with f.p. constant gives false warning
@ 2023-10-20 14:40 agner at agner dot org
  2023-10-20 15:29 ` [Bug c++/111897] " redi at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: agner at agner dot org @ 2023-10-20 14:40 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111897

            Bug ID: 111897
           Summary: Initialization of _Float16 with f.p. constant gives
                    false warning
           Product: gcc
           Version: 13.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: agner at agner dot org
  Target Milestone: ---

Initializing a _Float16 gives false warning. Example:

  _Float16 A = 1.0;

This gives the "warning: converting to ‘_Float16’ from ‘double’ with greater
conversion rank", with a link to 
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1467r4.html#implicit

However, this link says that implicit conversion is allowed in initialization
with a constant. See section 5.7.3 and the example in 5.6.1 in the linked
document.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/111897] Initialization of _Float16 with f.p. constant gives false warning
  2023-10-20 14:40 [Bug c++/111897] New: Initialization of _Float16 with f.p. constant gives false warning agner at agner dot org
@ 2023-10-20 15:29 ` redi at gcc dot gnu.org
  2023-10-21  5:41 ` agner at agner dot org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: redi at gcc dot gnu.org @ 2023-10-20 15:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111897

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The examples in 5.6.1 are not the standard, so are not authoritative.

The wording change in 5.7.3 alters [dcl.init.list] which is about list
initialization, which is not relevant here. That says that converting 1.0 to
_Float16 is not a narrowing conversion, but copy initialization (as used in
your example) doesn't reject narrowing conversions anyway. And this isn't a
-Wnarrowing warning.

Had you written `_Float16 A{1.0};` then it would be list-init, and I think the
warning is wrong for that case.

I think the relevant wording for your example is [dcl.init.general] p16 (16.9):

Otherwise, the initial value of the object being initialized is the (possibly
converted) value of the
initializer expression. A standard conversion sequence (7.3) is used to convert
the initializer expression
to a prvalue of the cv-unqualified version of the destination type; no
user-defined conversions are
considered. If the conversion cannot be done, the initialization is ill-formed.


The relevant kind of standard conversion sequence here is a floating-point
conversion, as defined in 7.3.10 [conv.double]. That does not permit
conversions to types of lesser rank. So the conversion is ill-formed.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/111897] Initialization of _Float16 with f.p. constant gives false warning
  2023-10-20 14:40 [Bug c++/111897] New: Initialization of _Float16 with f.p. constant gives false warning agner at agner dot org
  2023-10-20 15:29 ` [Bug c++/111897] " redi at gcc dot gnu.org
@ 2023-10-21  5:41 ` agner at agner dot org
  2023-10-25  7:40 ` agner at agner dot org
  2023-10-25  9:31 ` redi at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: agner at agner dot org @ 2023-10-21  5:41 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111897

--- Comment #2 from Agner Fog <agner at agner dot org> ---
Thank you Jonathan.

The problem is that the C++ standard is becoming so complicated that nobody can
master it, not even the persons who wrote the example in the proposal.

`_Float16 A{1.0};` gives a warning, which apparently is wrong.
`_Float16 A = 1;` gives no warning.
`_Float16 A = 1.5f16;` gives no warning, but I am not sure the f16 suffix is
supported by all compilers

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/111897] Initialization of _Float16 with f.p. constant gives false warning
  2023-10-20 14:40 [Bug c++/111897] New: Initialization of _Float16 with f.p. constant gives false warning agner at agner dot org
  2023-10-20 15:29 ` [Bug c++/111897] " redi at gcc dot gnu.org
  2023-10-21  5:41 ` agner at agner dot org
@ 2023-10-25  7:40 ` agner at agner dot org
  2023-10-25  9:31 ` redi at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: agner at agner dot org @ 2023-10-25  7:40 UTC (permalink / raw)
  To: gcc-bugs

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 <agner@agner.org>
Sent: Tuesday, October 24, 2023 10:26 PM
To: David Olsen <dolsen@nvidia.com>; 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 = 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 <agner@agner.org>
    Sent: Tuesday, October 24, 2023 8:03 AM
    To: David Olsen <dolsen@nvidia.com>; griwes@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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/111897] Initialization of _Float16 with f.p. constant gives false warning
  2023-10-20 14:40 [Bug c++/111897] New: Initialization of _Float16 with f.p. constant gives false warning agner at agner dot org
                   ` (2 preceding siblings ...)
  2023-10-25  7:40 ` agner at agner dot org
@ 2023-10-25  9:31 ` redi at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: redi at gcc dot gnu.org @ 2023-10-25  9:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111897

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
So closing as not-a-bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-10-25  9:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-20 14:40 [Bug c++/111897] New: Initialization of _Float16 with f.p. constant gives false warning agner at agner dot org
2023-10-20 15:29 ` [Bug c++/111897] " redi at gcc dot gnu.org
2023-10-21  5:41 ` agner at agner dot org
2023-10-25  7:40 ` agner at agner dot org
2023-10-25  9:31 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).