Live data from Hacker News

The PImpl idiom and the C++26 std:indirect type

mariusbancila.ro

61–70 of 122 posts

Re: The PImpl idiom and the C++26 std:indirect type

#61
post #50

Earlier quoted context omitted.

But if the pimpl size grows too big, you're forced to break ABI? And before it grows too big, it wastes memory. For your use cases it may not matter, and the saved pointer indirection may be more important, but maybe the person who has a million item vector of objects doesn't appreciate a 300% "just in case" memory overhead. The overhead may also hurt cache hits. If you're doing this to save the pointer indirection,…

"Breaking ABI" isn't an issue unless you can't compile your code anymore. It's pathetic that C++ has been so hamstrung over ABI that we're willing to stop improving.

Not everyone works at Google and builds all binaries from scratch from a monorepo every time. And even then, maybe even Google doesn't rebuild libstdc++ as part of this.

GNURadio consistently uses pimpl for blocks, as I understand it mainly for ABI.

> willing to stop improving.

I think that dismissing it like that shows a naive understanding of execution environments, binary interface design, and in general systems software engineering.

Re: The PImpl idiom and the C++26 std:indirect type

#62
post #50

Earlier quoted context omitted.

But if the pimpl size grows too big, you're forced to break ABI? And before it grows too big, it wastes memory. For your use cases it may not matter, and the saved pointer indirection may be more important, but maybe the person who has a million item vector of objects doesn't appreciate a 300% "just in case" memory overhead. The overhead may also hurt cache hits. If you're doing this to save the pointer indirection,…

"Breaking ABI" isn't an issue unless you can't compile your code anymore. It's pathetic that C++ has been so hamstrung over ABI that we're willing to stop improving.

Unfortunately I have some customers of my library that won't recompile. Hard to blame them because it is safety critical and needs recertification. In just glad the certification process is willing to not recertify my code when I change it

Re: The PImpl idiom and the C++26 std:indirect type

#63
post #18

Earlier quoted context omitted.

The point of each improvement is fewer easily-made errors. Having implicit deep copying handled avoids lots of errors with manually implementing it the oldest way.

Well that's a lie. I've long been back to raw pointers and it's by far the easiest way to do it. All of Pimpl, unique_ptr, and whatever other clever mechanism (I'm not even looking at std::indirect anymore) just aren't really ergonomic. Nobody needs "deep copying", ever. It's not even well defined what it should mean (i.e. how deep etc.). It's purely a theoretical problem with no good practical (one-fits-all) solutio…

Easiest way to make a silly mistake and have your program break from memory safety errors.

Re: The PImpl idiom and the C++26 std:indirect type

#64
post #63

Earlier quoted context omitted.

Well that's a lie. I've long been back to raw pointers and it's by far the easiest way to do it. All of Pimpl, unique_ptr, and whatever other clever mechanism (I'm not even looking at std::indirect anymore) just aren't really ergonomic. Nobody needs "deep copying", ever. It's not even well defined what it should mean (i.e. how deep etc.). It's purely a theoretical problem with no good practical (one-fits-all) solutio…

Easiest way to make a silly mistake and have your program break from memory safety errors.

Well, the best way to prevent mistakes is to make everything super complicated and damn hard to do. The best way to prevent mistakes is to approach it to do the essential stuff and avoid the fluffy stuff.

Re: The PImpl idiom and the C++26 std:indirect type

#65
post #50
post #23

I have a little class called EImpl that is kind of like std::indirect except that it embeds the impl instead of pointing to it. It takes three template parameters: an embedded struct, a size and an alignment. It static_asserts that the embedded struct fits in the size and alignment, and it embeds it with approximately zero overhead. It’s about as easy to use as any other pImpl technique.

But if the pimpl size grows too big, you're forced to break ABI? And before it grows too big, it wastes memory. For your use cases it may not matter, and the saved pointer indirection may be more important, but maybe the person who has a million item vector of objects doesn't appreciate a 300% "just in case" memory overhead. The overhead may also hurt cache hits. If you're doing this to save the pointer indirection,…

I use it in a monorepo to break compile-time dependencies. If I need to adjust the size, I spend a minute or two rebuilding.

Re: The PImpl idiom and the C++26 std:indirect type

#66

> Never null: it always holds a value, except in the moved-from state I am wondering why C++ can't implement "non-null" unique_ptr version in the same way? As I know, that the main argument against implementing it is, that it's can't be done, since move-out unique_ptr still can be null.

I've been thinking about things like that a bit. I see a very useful and safe Rust pattern, and wonder if I can possibly implement it in C++. Mostly the answer is no, because C++ is too powerful.

I would love to proved wrong, but everything I can think of still leaves a footgun that's easy to trigger by accident, and thus negates the point of the solution.

I think the can't-reference-after-moved-from and objects-are-not-Copy-by-default are key to creating these types (at least enforced at compile time). And that would require major language changes, at least as big as the C++11 changes.

Re: The PImpl idiom and the C++26 std:indirect type

#67
post #65
post #50

Earlier quoted context omitted.

But if the pimpl size grows too big, you're forced to break ABI? And before it grows too big, it wastes memory. For your use cases it may not matter, and the saved pointer indirection may be more important, but maybe the person who has a million item vector of objects doesn't appreciate a 300% "just in case" memory overhead. The overhead may also hurt cache hits. If you're doing this to save the pointer indirection,…

I use it in a monorepo to break compile-time dependencies. If I need to adjust the size, I spend a minute or two rebuilding.

Yup, agree that in some cases this fixes it. Indeed, in another comment[1] on this comment branch I said "Not everyone works at Google and builds all binaries from scratch from a monorepo every time".

So you're only trying to solve compile time issues (incremental and not)? Maybe the right long term solution is C++ modules, instead? And maybe "just" a matter of having your build environment support modules?

[1] https://news.ycombinator.com/item?id=49034842

Re: The PImpl idiom and the C++26 std:indirect type

#68
post #66

> Never null: it always holds a value, except in the moved-from state I am wondering why C++ can't implement "non-null" unique_ptr version in the same way? As I know, that the main argument against implementing it is, that it's can't be done, since move-out unique_ptr still can be null.

I've been thinking about things like that a bit. I see a very useful and safe Rust pattern, and wonder if I can possibly implement it in C++. Mostly the answer is no, because C++ is too powerful. I would love to proved wrong, but everything I can think of still leaves a footgun that's easy to trigger by accident, and thus negates the point of the solution. I think the can't-reference-after-moved-from and objects-are-…

Static analysis is the answer for some of these questions.

While many of us that like C++, would wish for a different evolution process, some of this stuff can be enforced by static analysis tooling.

Just like despite being safer than C++, we still use Sonar, FindBugs, FxCop/Roslyn Analysers, go vet, rust clippy, one more reason to actually use Sonar, clang-tidy, PVS, MSVC analyse,... with languages like C and C++.

In some of these you can add your own rules even, even if not always that straightforward.

Re: The PImpl idiom and the C++26 std:indirect type

#69

Where are we with modules, isn't pimpl there largely to avoid costs related to including the world? I was pondering on why he was putting the defaulted methods in the cpp, any particular reasons? I did realize that the indirect version is required to be in the cpp since the header won't know how to copy without knowing the definition of the impl class.

Even with modules, if you expose such types over the ABI, naturally the machine code memory layout will change, this is an issue regardless of the language.

Re: The PImpl idiom and the C++26 std:indirect type

#70
post #38
post #35

Earlier quoted context omitted.

We put #define WIN32_LEAN_AND_MEAN 1 #include In precompiled headers to solve that particular problem.

That's kind of a hack, still best only used in implementation files, not headers.

That may be true, but it's a "hack" that has caused me approximately 1 issue in 15 years of writing C++ professionally, and that issue was a problem with our build system not the precompiled header.

> Still best only used in implementation files, not headers.

We only compile implementation files!

Post reply on HN