* 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
[parent not found: <BFCFC341-004F-4FC9-A298-6DFAB390815D@globus.software>]
* 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).