Date: Tue, 4 Feb 2025 17:13:42 -0500
On Tue, Feb 4, 2025 at 4:11 PM Hyman Rosen via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> "My compilation is too slow when I include standard headers" sounds like a
> tooling issue, not something the language needs to address.
>
What kind of tooling are you imagining that would be a better solution than
providing authoritatively correct forward declaration headers (a kind of
"<iosfwd> for everything!" approach)?
On Tue, Feb 4, 2025 at 3:59 PM Tiago Freire via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> The ability to forward declare nested classes is one of my motivations.
>>
>>
>>
>> I wouldn’t go into the direction of requiring compilers to automatically
>> just “find me the right header files” and not specify how that works.
>>
>> If I may take the discussion around “#pragma once”, I would say that lose
>> rules regarding how the magic happens is a recipe for disaster.
>>
>>
>>
>> From my understanding you can actually do quite a lot without much magic.
>>
>>
>>
>> I have found 2 categories of problems.
>>
>> 1. Non-aliased types. Where the forwarded type is the actual name of the
>> type. It will be one of class, struct, or union, without needing to specify
>> it as a class, struct, or union.
>>
>> 2. Aliased types. A type "defined" by using typedef or using.
>>
>>
>>
>> 1 is super easy, it looks like pretty much everything works, template,
>> constexpr, function calls, etc... I haven't noticed a problem yet.
>> Everything that you can do with a trivially forward declared type you would
>> be able to do with this. The only difference is you don’t have to specify
>> class, struct, or union, it’s one of those 3.
>>
>>
>>
>>
>>
>> 2 is much more complicated, because the actual name will be different
>> from the know name. (ex. std::string)
>>
>>
>>
>> I think you can make function calls sort of work.
>>
>> As long as function prototypes are defined with the same name as the
>> alias name, it is trivial to resolve. For that you would need extra data in
>> object files to keep track of aliases so that it can resolve the actual
>> names when linking. I think that information would also need to be
>> transitive and passed around static libraries such that you can handle
>> linking between multiple libraries, it’s more to track but looks doable.
>>
>>
>>
>> The problem starts when functions parameters don't match the alias name,
>> it is possible in some situations to resolve the right symbol from an alias
>> look up, but it gets tricky when types are derived types, and you need to
>> deal with promotion rules. That may require some additional compile time
>> code generation. But then again that doesn’t work with trivial forward
>> declared types either.
>>
>>
>>
>> For constexpr functions, you can make it work if the name used is the
>> same (or a qualified version thereof), if it isn’t, then link time it would
>> be to late to do anything.
>>
>>
>>
>> I would be ok for this type of forward declaration to not work with
>> function calls (either regular or constexpr/consteval) if the used type
>> name in those functions is not the alias name or a qualified version of it,
>> as long as it would work if the name used is the alias name.
>>
>>
>>
>> Templates would only work in 2 scenarios. If the template doesn’t have
>> any specialization at all, or the specialization explicitly uses the alias
>> name.
>>
>> If the template provides any specialization and none of them explicitly
>> uses the alias name, there’s no way for the compiler to know what code to
>> generate because it can not tell if the alias name aliases any of the
>> specializations provided.
>>
>> It might be possible to do something with link time code generation, but
>> I’m not going to advocate to hoist all of the code generation to link time.
>> And, I would be ok if this wouldn’t work in this scenario either.
>>
>>
>>
>>
>> ------------------------------
>>
>> *From:* Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf
>> of Thiago Macieira via Std-Proposals <std-proposals_at_[hidden]>
>> *Sent:* Tuesday, February 4, 2025 5:02:26 PM
>> *To:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
>> *Cc:* Thiago Macieira <thiago_at_[hidden]>
>> *Subject:* Re: [std-proposals] Specify the mangled name
>>
>>
>>
>> On Tuesday 4 February 2025 04:23:45 Pacific Standard Time Tiago Freire
>> via Std-
>> Proposals wrote:
>> > This isn't exactly crazy.
>> >
>> > I'm currently working on this in order to be able to forward declare,
>> not
>> > just any class, but any type.
>> >
>> > you would just do something like:
>> >
>> > typename MyType;
>>
>> The only way this would work is if the compiler translates this to an
>> #include
>> or import of something provided by said library so the type gets forward-
>> declared. Going back to Frederick's example, the compiler has no way of
>> knowing whether the snippet he gave was correct or if it needed to be:
>>
>> namespace std {
>> inline namespace __1 {
>> template<class T> class less;
>> template<class T> class allocator;
>> template< class Key, class Compare = less<Key>, class
>> Allocator = allocator<Key> > class set;
>> }
>> }
>>
>> Since the compiler can't know this at all, it needs to come from the
>> library
>> itself. That in turn allows us to extend the mechanism for other
>> libraries
>> besides the Standard one. We turn the problem from "what is the nature of
>> this
>> type" to "how do I find a small header that will declare it for me". And
>> the
>> Standard can simply do a jedi mind trick here and say it is
>> implementation-
>> defined how such a file is found.
>>
>> The easiest of which would be that it includes <fwd/NS/NS/.../name> or
>> <NS/NS/
>> name> (whichever exists first) and we just rely on the include system to
>> resolve it. For me, the great thing about this is that it would "just
>> work"
>> right now for practically all Qt classes, from Qt 4 (2005) onwards.
>>
>> We'd ask the compilers to provide tooling to auto-generate those files
>> for us,
>> as they're compiling sources. This would simplify everyone's lives.
>> Moreover,
>> a smart compiler here could also perform an ODR verification that the
>> types
>> were declared the same way everywhere.
>>
>>
>> Finally, one extra feature I'd like to see is the ability to
>> forward-declare
>> nested classes, such as:
>>
>> class Outer;
>> struct Outer:: public Inner;
>> --
>> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>> Principal Engineer - Intel DCAI Platform & System Engineering
>>
>>
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
std-proposals_at_[hidden]> wrote:
> "My compilation is too slow when I include standard headers" sounds like a
> tooling issue, not something the language needs to address.
>
What kind of tooling are you imagining that would be a better solution than
providing authoritatively correct forward declaration headers (a kind of
"<iosfwd> for everything!" approach)?
On Tue, Feb 4, 2025 at 3:59 PM Tiago Freire via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> The ability to forward declare nested classes is one of my motivations.
>>
>>
>>
>> I wouldn’t go into the direction of requiring compilers to automatically
>> just “find me the right header files” and not specify how that works.
>>
>> If I may take the discussion around “#pragma once”, I would say that lose
>> rules regarding how the magic happens is a recipe for disaster.
>>
>>
>>
>> From my understanding you can actually do quite a lot without much magic.
>>
>>
>>
>> I have found 2 categories of problems.
>>
>> 1. Non-aliased types. Where the forwarded type is the actual name of the
>> type. It will be one of class, struct, or union, without needing to specify
>> it as a class, struct, or union.
>>
>> 2. Aliased types. A type "defined" by using typedef or using.
>>
>>
>>
>> 1 is super easy, it looks like pretty much everything works, template,
>> constexpr, function calls, etc... I haven't noticed a problem yet.
>> Everything that you can do with a trivially forward declared type you would
>> be able to do with this. The only difference is you don’t have to specify
>> class, struct, or union, it’s one of those 3.
>>
>>
>>
>>
>>
>> 2 is much more complicated, because the actual name will be different
>> from the know name. (ex. std::string)
>>
>>
>>
>> I think you can make function calls sort of work.
>>
>> As long as function prototypes are defined with the same name as the
>> alias name, it is trivial to resolve. For that you would need extra data in
>> object files to keep track of aliases so that it can resolve the actual
>> names when linking. I think that information would also need to be
>> transitive and passed around static libraries such that you can handle
>> linking between multiple libraries, it’s more to track but looks doable.
>>
>>
>>
>> The problem starts when functions parameters don't match the alias name,
>> it is possible in some situations to resolve the right symbol from an alias
>> look up, but it gets tricky when types are derived types, and you need to
>> deal with promotion rules. That may require some additional compile time
>> code generation. But then again that doesn’t work with trivial forward
>> declared types either.
>>
>>
>>
>> For constexpr functions, you can make it work if the name used is the
>> same (or a qualified version thereof), if it isn’t, then link time it would
>> be to late to do anything.
>>
>>
>>
>> I would be ok for this type of forward declaration to not work with
>> function calls (either regular or constexpr/consteval) if the used type
>> name in those functions is not the alias name or a qualified version of it,
>> as long as it would work if the name used is the alias name.
>>
>>
>>
>> Templates would only work in 2 scenarios. If the template doesn’t have
>> any specialization at all, or the specialization explicitly uses the alias
>> name.
>>
>> If the template provides any specialization and none of them explicitly
>> uses the alias name, there’s no way for the compiler to know what code to
>> generate because it can not tell if the alias name aliases any of the
>> specializations provided.
>>
>> It might be possible to do something with link time code generation, but
>> I’m not going to advocate to hoist all of the code generation to link time.
>> And, I would be ok if this wouldn’t work in this scenario either.
>>
>>
>>
>>
>> ------------------------------
>>
>> *From:* Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf
>> of Thiago Macieira via Std-Proposals <std-proposals_at_[hidden]>
>> *Sent:* Tuesday, February 4, 2025 5:02:26 PM
>> *To:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
>> *Cc:* Thiago Macieira <thiago_at_[hidden]>
>> *Subject:* Re: [std-proposals] Specify the mangled name
>>
>>
>>
>> On Tuesday 4 February 2025 04:23:45 Pacific Standard Time Tiago Freire
>> via Std-
>> Proposals wrote:
>> > This isn't exactly crazy.
>> >
>> > I'm currently working on this in order to be able to forward declare,
>> not
>> > just any class, but any type.
>> >
>> > you would just do something like:
>> >
>> > typename MyType;
>>
>> The only way this would work is if the compiler translates this to an
>> #include
>> or import of something provided by said library so the type gets forward-
>> declared. Going back to Frederick's example, the compiler has no way of
>> knowing whether the snippet he gave was correct or if it needed to be:
>>
>> namespace std {
>> inline namespace __1 {
>> template<class T> class less;
>> template<class T> class allocator;
>> template< class Key, class Compare = less<Key>, class
>> Allocator = allocator<Key> > class set;
>> }
>> }
>>
>> Since the compiler can't know this at all, it needs to come from the
>> library
>> itself. That in turn allows us to extend the mechanism for other
>> libraries
>> besides the Standard one. We turn the problem from "what is the nature of
>> this
>> type" to "how do I find a small header that will declare it for me". And
>> the
>> Standard can simply do a jedi mind trick here and say it is
>> implementation-
>> defined how such a file is found.
>>
>> The easiest of which would be that it includes <fwd/NS/NS/.../name> or
>> <NS/NS/
>> name> (whichever exists first) and we just rely on the include system to
>> resolve it. For me, the great thing about this is that it would "just
>> work"
>> right now for practically all Qt classes, from Qt 4 (2005) onwards.
>>
>> We'd ask the compilers to provide tooling to auto-generate those files
>> for us,
>> as they're compiling sources. This would simplify everyone's lives.
>> Moreover,
>> a smart compiler here could also perform an ODR verification that the
>> types
>> were declared the same way everywhere.
>>
>>
>> Finally, one extra feature I'd like to see is the ability to
>> forward-declare
>> nested classes, such as:
>>
>> class Outer;
>> struct Outer:: public Inner;
>> --
>> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>> Principal Engineer - Intel DCAI Platform & System Engineering
>>
>>
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2025-02-04 22:13:58