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