Date: Tue, 4 Feb 2025 21:16:20 +0000
I’ve not mentioned “compilation time” as a motivation.
Clean interfaces and hiding clutter are motivation enough, and that ca not be addressed by simple tooling.
From: Hyman Rosen <hyrosen_at_[hidden]>
Sent: Tuesday, February 4, 2025 10:11 PM
To: std-proposals_at_[hidden]g
Cc: Tiago Freire <tmiguelf_at_[hidden]>
Subject: Re: [std-proposals] Specify the mangled name
"My compilation is too slow when I include standard headers" sounds like a tooling issue, not something the language needs to address.
On Tue, Feb 4, 2025 at 3:59 PM Tiago Freire via Std-Proposals <std-proposals_at_[hidden]<mailto: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]<mailto:std-proposals-bounces_at_[hidden]>> on behalf of Thiago Macieira via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Sent: Tuesday, February 4, 2025 5:02:26 PM
To: std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]> <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Cc: Thiago Macieira <thiago_at_[hidden]<mailto: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<http://macieira.info> - thiago (AT) kde.org<http://kde.org>
Principal Engineer - Intel DCAI Platform & System Engineering
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]<mailto:Std-Proposals_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]<mailto:Std-Proposals_at_lists.isocpp.org>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Clean interfaces and hiding clutter are motivation enough, and that ca not be addressed by simple tooling.
From: Hyman Rosen <hyrosen_at_[hidden]>
Sent: Tuesday, February 4, 2025 10:11 PM
To: std-proposals_at_[hidden]g
Cc: Tiago Freire <tmiguelf_at_[hidden]>
Subject: Re: [std-proposals] Specify the mangled name
"My compilation is too slow when I include standard headers" sounds like a tooling issue, not something the language needs to address.
On Tue, Feb 4, 2025 at 3:59 PM Tiago Freire via Std-Proposals <std-proposals_at_[hidden]<mailto: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]<mailto:std-proposals-bounces_at_[hidden]>> on behalf of Thiago Macieira via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Sent: Tuesday, February 4, 2025 5:02:26 PM
To: std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]> <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Cc: Thiago Macieira <thiago_at_[hidden]<mailto: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<http://macieira.info> - thiago (AT) kde.org<http://kde.org>
Principal Engineer - Intel DCAI Platform & System Engineering
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]<mailto:Std-Proposals_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]<mailto:Std-Proposals_at_lists.isocpp.org>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-02-04 21:16:25