public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* Forward declaration and std::future
@ 2021-09-12  9:36 Evgen Bodunov
  2021-09-12 18:19 ` Jonathan Wakely
  0 siblings, 1 reply; 5+ messages in thread
From: Evgen Bodunov @ 2021-09-12  9:36 UTC (permalink / raw)
  To: libstdc++

Hello everyone,

During development of valhalla routing project I stumbled upon compilation error on gcc + libstdc++ 11 and newer when std::future constructed from forward declared class. Live example is there: https://godbolt.org/z/rEx3Eonsz It builds on gcc prior to v11. and on any clang with libc++.

/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits: In instantiation of 'struct std::is_destructible<test_data>':
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21:   required from 'class std::promise<test_data>'
<source>:8:29:   required from here
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:849:52: error: static assertion failed: template argument must be a complete class or an unbounded array
  849 |       static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:849:52: note: 'std::__is_complete_or_unbounded<std::__type_identity<test_data> >((std::__type_identity<test_data>{}, std::__type_identity<test_data>()))' evaluates to false
In file included from <source>:1:
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future: In instantiation of 'class std::promise<test_data>':
<source>:8:29:   required from here
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21: error: static assertion failed: result type must be destructible
 1065 |       static_assert(is_destructible<_Res>{},
      |                     ^~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21: note: 'std::is_destructible<test_data>{}' evaluates to false
Compiler returned: 1

Is that static assert is really required? May be then it should correctly process forward declared types?

WBR,
Evgen Bodunov.

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

* Re: Forward declaration and std::future
  2021-09-12  9:36 Forward declaration and std::future Evgen Bodunov
@ 2021-09-12 18:19 ` Jonathan Wakely
       [not found]   ` <BFCFC341-004F-4FC9-A298-6DFAB390815D@globus.software>
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2021-09-12 18:19 UTC (permalink / raw)
  To: Evgen Bodunov; +Cc: libstdc++

On Sun, 12 Sep 2021, 10:36 Evgen Bodunov, <evgen@globus.software> wrote:

> Hello everyone,
>
> During development of valhalla routing project I stumbled upon compilation
> error on gcc + libstdc++ 11 and newer when std::future constructed from
> forward declared class. Live example is there:
> https://godbolt.org/z/rEx3Eonsz It builds on gcc prior to v11. and on any
> clang with libc++.
>
> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits: In
> instantiation of 'struct std::is_destructible<test_data>':
> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21:
>  required from 'class std::promise<test_data>'
> <source>:8:29:   required from here
> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:849:52:
> error: static assertion failed: template argument must be a complete class
> or an unbounded array
>   849 |
>  static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
>       |
>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:849:52:
> note: 'std::__is_complete_or_unbounded<std::__type_identity<test_data>
> >((std::__type_identity<test_data>{}, std::__type_identity<test_data>()))'
> evaluates to false
> In file included from <source>:1:
> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future: In
> instantiation of 'class std::promise<test_data>':
> <source>:8:29:   required from here
> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21:
> error: static assertion failed: result type must be destructible
>  1065 |       static_assert(is_destructible<_Res>{},
>       |                     ^~~~~~~~~~~~~~~~~~~~~~~
> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21: note:
> 'std::is_destructible<test_data>{}' evaluates to false
> Compiler returned: 1
>
> Is that static assert is really required? May be then it should correctly
> process forward declared types?
>

The standard says your code has undefined behaviour. The assertion is
pointing out your mistake.

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

* Re: Forward declaration and std::future
       [not found]   ` <BFCFC341-004F-4FC9-A298-6DFAB390815D@globus.software>
@ 2021-09-12 20:04     ` Jonathan Wakely
  2021-09-13  8:32       ` Evgen Bodunov
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2021-09-12 20:04 UTC (permalink / raw)
  To: Evgen Bodunov; +Cc: libstdc++

On Sun, 12 Sep 2021, 19:30 Evgen Bodunov, <evgen@globus.software> wrote:

> Hello Jonathan,
>
> Please, could you refer exact part and version of the standard?
>


Please reply to the mailing list, not just to me.

Every version of the standard has the same requirement, see
http://eel.is/c++draft/requirements#res.on.functions-2.5

std::promise requires its result type to be destructible. We are allowed to
assert that by using is_destructible because we can assume the type is
complete, because [res.on.functions] says it must be.

In a correct program, the assertion will not fail.





> On 12.09.2021, at 20:19, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>
>
>
> On Sun, 12 Sep 2021, 10:36 Evgen Bodunov, <evgen@globus.software> wrote:
>
>> Hello everyone,
>>
>> During development of valhalla routing project I stumbled upon
>> compilation error on gcc + libstdc++ 11 and newer when std::future
>> constructed from forward declared class. Live example is there:
>> https://godbolt.org/z/rEx3Eonsz It builds on gcc prior to v11. and on
>> any clang with libc++.
>>
>> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits: In
>> instantiation of 'struct std::is_destructible<test_data>':
>> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21:
>>  required from 'class std::promise<test_data>'
>> <source>:8:29:   required from here
>> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:849:52:
>> error: static assertion failed: template argument must be a complete class
>> or an unbounded array
>>   849 |
>>  static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
>>       |
>>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
>> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:849:52:
>> note: 'std::__is_complete_or_unbounded<std::__type_identity<test_data>
>> >((std::__type_identity<test_data>{}, std::__type_identity<test_data>()))'
>> evaluates to false
>> In file included from <source>:1:
>> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future: In
>> instantiation of 'class std::promise<test_data>':
>> <source>:8:29:   required from here
>> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21:
>> error: static assertion failed: result type must be destructible
>>  1065 |       static_assert(is_destructible<_Res>{},
>>       |                     ^~~~~~~~~~~~~~~~~~~~~~~
>> /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/future:1065:21:
>> note: 'std::is_destructible<test_data>{}' evaluates to false
>> Compiler returned: 1
>>
>> Is that static assert is really required? May be then it should correctly
>> process forward declared types?
>>
>
> The standard says your code has undefined behaviour. The assertion is
> pointing out your mistake.
>
>
>
>

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

* Re: Forward declaration and std::future
  2021-09-12 20:04     ` Jonathan Wakely
@ 2021-09-13  8:32       ` Evgen Bodunov
  2021-09-13  8:52         ` Jonathan Wakely
  0 siblings, 1 reply; 5+ messages in thread
From: Evgen Bodunov @ 2021-09-13  8:32 UTC (permalink / raw)
  To: libstdc++

> On 12.09.2021, at 22:04, Jonathan Wakely via Libstdc++ <libstdc++@gcc.gnu.org> wrote:
> 
> On Sun, 12 Sep 2021, 19:30 Evgen Bodunov, <evgen@globus.software> wrote:
>> 
>> Please, could you refer exact part and version of the standard?
>> 
> 
> Please reply to the mailing list, not just to me.
> 
> Every version of the standard has the same requirement, see
> http://eel.is/c++draft/requirements#res.on.functions-2.5
> 
> std::promise requires its result type to be destructible. We are allowed to
> assert that by using is_destructible because we can assume the type is
> complete, because [res.on.functions] says it must be.
> 
> In a correct program, the assertion will not fail.

Thank you for the detailed response. For some reason I expected that if there is not enough 
type data to compile the code correctly, there would be an error from the compiler, not from 
static_assert. As for example in case of inheritance or creating objects from a type that was 
forward declared. And in this case there is an error saying that the class doesn't have a 
destructor, although it actually exists and this is confusing.


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

* Re: Forward declaration and std::future
  2021-09-13  8:32       ` Evgen Bodunov
@ 2021-09-13  8:52         ` Jonathan Wakely
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Wakely @ 2021-09-13  8:52 UTC (permalink / raw)
  To: Evgen Bodunov; +Cc: libstdc++

On Mon, 13 Sept 2021 at 09:33, Evgen Bodunov <evgen@globus.software> wrote:
>
> > On 12.09.2021, at 22:04, Jonathan Wakely via Libstdc++ <libstdc++@gcc.gnu.org> wrote:
> >
> > On Sun, 12 Sep 2021, 19:30 Evgen Bodunov, <evgen@globus.software> wrote:
> >>
> >> Please, could you refer exact part and version of the standard?
> >>
> >
> > Please reply to the mailing list, not just to me.
> >
> > Every version of the standard has the same requirement, see
> > http://eel.is/c++draft/requirements#res.on.functions-2.5
> >
> > std::promise requires its result type to be destructible. We are allowed to
> > assert that by using is_destructible because we can assume the type is
> > complete, because [res.on.functions] says it must be.
> >
> > In a correct program, the assertion will not fail.
>
> Thank you for the detailed response. For some reason I expected that if there is not enough
> type data to compile the code correctly, there would be an error from the compiler, not from
> static_assert. As for example in case of inheritance or creating objects from a type that was
> forward declared. And in this case there is an error saying that the class doesn't have a
> destructor, although it actually exists and this is confusing.


The relevant errors are:

error: static assertion failed: template argument must be a complete
class or an unbounded array
error: static assertion failed: result type must be destructible

Neither of these says there is no destructor. It says the type is
incomplete, and not destructible. You cannot tell if a type is
destructible if it's incomplete, because you can't tell if it has a
deleted or private/protected destructor, because it's incomplete.

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

end of thread, other threads:[~2021-09-13  8:52 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-12  9:36 Forward declaration and std::future Evgen Bodunov
2021-09-12 18:19 ` Jonathan Wakely
     [not found]   ` <BFCFC341-004F-4FC9-A298-6DFAB390815D@globus.software>
2021-09-12 20:04     ` Jonathan Wakely
2021-09-13  8:32       ` Evgen Bodunov
2021-09-13  8:52         ` Jonathan Wakely

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).