Earlier quoted context omitted.
That would be an ABI break which is just not happening, and you know it. As it is we’ve decided it’s more important to be able to use std span from libc++ on clang than it is to have an optimised version for people on their tool chain.
So you're saying that turning std::span from a standard library class into a language feature wouldn't break the ABI? How so? How would such a language construct fit into the existing ABI? (for context: parent is referring to the fact that x64 calling conventions mandate structs larger than 64 bits to be passed in memory, which means that passing a 128bit std::span is going to be less efficient than passing a separat…
Reflection for C++26
201–210 of 214 posts
Re: Reflection for C++26
#202Earlier quoted context omitted.
Also that the features c++ is getting are bolt on additions that we already have solutions for. I think fmt is a great example - fmt is a header only library that can be dropped in. Meanwhile std format was standardised without printing to stout. That took 3 years to standardise. Meanwhile we’re working on things like ranges, and instead of implementing them in the language it’s shoe horned in as a library feature -…
Ha! Modules. I wrote a basic version of that in 2006 for Boost. This is as big a useless mess as web components. It feels like c++ is in the legacy category with x86, still here, tolerable due to exponential efforts, and still dying for simpler solutions that aren't beholden to decades-old design mistakes. (variable instruction width, context-sensitive grammar, #include model, etc).
Re: Reflection for C++26
#203While I love this paper and this proposal in general, as a C++ developer every time C++ adds a new major feature I get somewhat worried about two things: 1. how immense the language has become, and how hard it got to learn and implement 2. how "modernising" C++ gives developers less incentives to convince management to switch to safer languages While I like C++ and how crazy powerful it is, I also must admit decades…
I think the focus on smart pointers is a huge mistake. Code bases using shared_ptr inevitably will have cycles and memory leaks, and no one understands the graphs any more. Tree algorithms that are simple in literature get bloated and slow with shared_ptr. The only issue with pointers in C++, which C does not have , is that so many things are copied around by default if one is using classes. So the way to deal with t…
There are all sorts of issues with pointers (and not just in C++) - which are inherent to their use. They can point anywhere! They're mutable! They can be null! It's difficult/impossible to ensure they hold a valid value!
Common wisdom is to avoid excessive use of pointers when you don't _really_ need - even smart pointers.
Consider this fine presentation for example:
"Don't use fking pointers" https://klmr.me/slides/modern-cpp/#1
Use references, especially as function parameters,
* Returning values in modern C++ typically does _not_ involve any copying.
* If you want to indicate the possibility that your value is uninitialized/invalid - use std::optional, which can hold either an actual T value or an std::nullopt (being in an "empty" or "value-less" state).
* If your data is in some buffer (or span, or vector etc.), you can use offsets into that buffer.
* Many uses of pointers are due to the "need" to utilize polymorphism: myobj->foo() . Well, typically, you know the real type at compile-time, and can write a freestanding foo() function, which is polymorphic via overloading, or being templated over its parameter's type.
* And speaking of virtual methods and class hierarchies, you can often make do with a template parameter instead of a choice of subclass; or with an std::variant
Re: Reflection for C++26
#204Finally. I think there have been proposals since C++17 at least, and all I really wanted is for them to solve the common problem of basic static reflection for enums (without hacks like magic_enum uses).
magic_enum is killing my build time with endless template instantiations. Is this going to be faster?
Yes, there is magic_enum already - and we based this implementation on the core of magic_enum, but refocused for C++20, using some of the key features of this language version such constexpr algorithms, std::source_location and concepts; we also improved on and expanded the API.
Re: Reflection for C++26
#205Earlier quoted context omitted.
That would be an ABI break which is just not happening, and you know it. As it is we’ve decided it’s more important to be able to use std span from libc++ on clang than it is to have an optimised version for people on their tool chain.
So you're saying that turning std::span from a standard library class into a language feature wouldn't break the ABI? How so? How would such a language construct fit into the existing ABI? (for context: parent is referring to the fact that x64 calling conventions mandate structs larger than 64 bits to be passed in memory, which means that passing a 128bit std::span is going to be less efficient than passing a separat…
Other ABIs might have different constraints but there is no reason why they couldn't special case std::span. In fact if span was a built-in type there is nothing preventing a compiler form picking a suboptimal ABI and being stuck with it. In any case it is not a standardization issue, but purely a QoI.
Re: Reflection for C++26
#206Earlier quoted context omitted.
So you're saying that turning std::span from a standard library class into a language feature wouldn't break the ABI? How so? How would such a language construct fit into the existing ABI? (for context: parent is referring to the fact that x64 calling conventions mandate structs larger than 64 bits to be passed in memory, which means that passing a 128bit std::span is going to be less efficient than passing a separat…
What is the issue exactly? Span is trivially copyable and destructible and, at least with the Itanium ABI, it can be passed (and returned) via registers: https://gcc.godbolt.org/z/4rbcshve4 . Other ABIs might have different constraints but there is no reason why they couldn't special case std::span. In fact if span was a built-in type there is nothing preventing a compiler form picking a suboptimal ABI and being stuc…
>Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed as if they were integers of the same size. Structs or unions of other sizes are passed as a pointer to memory allocated by the caller.
https://learn.microsoft.com/en-us/cpp/build/x64-calling-conv...
Re: Reflection for C++26
#207Earlier quoted context omitted.
So you're saying that turning std::span from a standard library class into a language feature wouldn't break the ABI? How so? How would such a language construct fit into the existing ABI? (for context: parent is referring to the fact that x64 calling conventions mandate structs larger than 64 bits to be passed in memory, which means that passing a 128bit std::span is going to be less efficient than passing a separat…
What is the issue exactly? Span is trivially copyable and destructible and, at least with the Itanium ABI, it can be passed (and returned) via registers: https://gcc.godbolt.org/z/4rbcshve4 . Other ABIs might have different constraints but there is no reason why they couldn't special case std::span. In fact if span was a built-in type there is nothing preventing a compiler form picking a suboptimal ABI and being stuc…
> In any case it is not a standardization issue, but purely a QoI.
This is an enormous problem in the C++ ecosystem - playing hot-potato with whose fault it is, instead of trying to actually fix it. Span is a decent example, the standards committee get to say it's a vendor issue, and the vendors get to say that their hands are tied by the ABI. The result is that people spend time arguing about who should fix it rather than actually fixing it.
Re: Reflection for C++26
#208Earlier quoted context omitted.
What is the issue exactly? Span is trivially copyable and destructible and, at least with the Itanium ABI, it can be passed (and returned) via registers: https://gcc.godbolt.org/z/4rbcshve4 . Other ABIs might have different constraints but there is no reason why they couldn't special case std::span. In fact if span was a built-in type there is nothing preventing a compiler form picking a suboptimal ABI and being stuc…
The parent commenter handled the ABI question for me, but I want to respond to : > In any case it is not a standardization issue, but purely a QoI. This is an enormous problem in the C++ ecosystem - playing hot-potato with whose fault it is, instead of trying to actually fix it. Span is a decent example, the standards committee get to say it's a vendor issue, and the vendors get to say that their hands are tied by th…
In any case this has nothing to do with std::span being an technically a library type or a built in. There is really no fundamental difference between the two.
For example std::complex and std::initializer_list have special handling on many compilers, just to mention two types.
Re: Reflection for C++26
#209Earlier quoted context omitted.
The parent commenter handled the ABI question for me, but I want to respond to : > In any case it is not a standardization issue, but purely a QoI. This is an enormous problem in the C++ ecosystem - playing hot-potato with whose fault it is, instead of trying to actually fix it. Span is a decent example, the standards committee get to say it's a vendor issue, and the vendors get to say that their hands are tied by th…
That's all well and good, but what would you do exaclty? The standard comitee cannot impose an ABI as it would be ignored by implementors. Implementors either own the ABI (MS for example) and are responsible for their owns screwups or there are other bodies that are responsible (the informal forum for the inter-vendor Itanium ABI for another example). In any case this has nothing to do with std::span being an technic…
Start with having the standards committee accept that they are in fact where the buck stops, and that the language includes, whether they like it or not, the toolchain. They don't have to decide upon the toolchain, but their current MO of "toolchain/ABI issue == not our problem (except for when we decide we're not willing to make any backwards incompatible ABI changes, but only sometimes)." The vendors are already jumping through hoops to support what is being standardised (modules being the perfect example here).
I can't speak for std.complex as I've never had to use it, but I think initializer list would be a great example of "how much better would this be if it was special cased into the compiler". The benefit we would get from initialisation being consistent with the compiler far outweighs the benefit of being able to use libc++'s initialiser list with clang.
> There is really no fundamental difference between the two.
Except there is. If I write an implementation of the standard library, and provide an implementation of std span as (abbreviated) - https://gcc.godbolt.org/z/c1sz4neKG it's got to respect the various conventions instead of being treated as an opaque type (like a slice in go). If it's a `_Span`, the compiler is free to go "ok you're using this thing that I know all the internals of, and can reason about. I can elide bounds checks that don't pass muster, I can specify that I will generate code for this specific type that puts extent and data as registers in the following cases". But instead, on x64 (where I work 99% of the time so it's where my effort/knowledge is, sorry), we're bound by >64 == memory.
Now, you might call that a QOI issue, but I'd call it a design flaw that could have avoided an implementation issue, that we see on many features.
Re: Reflection for C++26
#210Earlier quoted context omitted.
That's all well and good, but what would you do exaclty? The standard comitee cannot impose an ABI as it would be ignored by implementors. Implementors either own the ABI (MS for example) and are responsible for their owns screwups or there are other bodies that are responsible (the informal forum for the inter-vendor Itanium ABI for another example). In any case this has nothing to do with std::span being an technic…
> That's all well and good, but what would you do exaclty? Start with having the standards committee accept that they are in fact where the buck stops, and that the language includes, whether they like it or not, the toolchain. They don't have to decide upon the toolchain, but their current MO of "toolchain/ABI issue == not our problem (except for when we decide we're not willing to make any backwards incompatible AB…
That's not an exception. The committee is not willing because the implementors explicitly said it is not going to happen, no matter how much Google cries.
> Except there is. If I write an implementation of the standard library, and provide an implementation of std span
if you write it as an user you are constrained by the ABI. But implementors are not: they can bless their own span with superpowers if they want to (in practice they would use special attributes). And there is no reason the compiler can't have builtin knowledge of the semantics of std::span (the same way it has knowledge of printf, malloc and the various math functions for example).
> But instead, on x64 (where I work 99% of the time so it's where my effort/knowledge is, sorry), we're bound by >64 == memory.
[Note this is an MSVC-specific ABI issue not a general x64 one. GCC uses the Itanium ABI on x64]
But the MSVC issue is really a red herring: there is a-priori no reason to expect they would have picked a better ABI for a built-in _Span. The committee cannot force compilers to be optimal (it can't even force conformance).
(Note I'm not singling out MSVC, GCC also has multiple less than ideal ABI decisions).