Comment by knorker

4 days ago

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, you should benchmark it for every use case, since negative cache effects may dwarf that gain.

Then again, extra padding can also help performance, for some workloads (especially multi threaded read/write against a vector of objects).

So without further context, there's no way to say if your way hurts or helps. It's certainly not a general solution.

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

> And before it grows too big, it wastes memory

how it wastes the memory? It's just a bytes array of the same size as struct. I would be more imposed on how idiomatic pimpl with heap allocation influences memory usage and cache hits

  • I read the parent commenter as proposing headroom.

    Because if it's an exact match, then it doesn't help at all with ABI compat, and arguably doesn't add anything. Well, aside from compile time, but that's maybe better solved with modules?

    • pimpl can solve several problems and allowing to extend struct without breaking ABI is the one is them. But even such implementation of pimpl breaks compile time and ABI dependency. You can't change size without breaking ABI, but still can change members, etc (e.g. replace current fields with heap allocated to extend without breaking ABI :))

"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.

    • If you want a fixed build environment, pick a toolchain and stick with it.

      If you want the latest and greatest, a willingness to rebuild your code seems like a reasonable prerequisite to me.

      If you need a binary blob that can withstand toolchain versioning, use a dynamically linked library.

      1 reply →

  • Because outside Linux and BSD distros, the large majority of C and C++ developers care about binary libraries, and companies do make a business out of it.

    So regardless of what WG14 and WG21 do, compiler vendors will ignore them, if it means angry customers.

    In design by committee languages, new standards are only relevant to the extent implementers actually care about them.

  • 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