Bar *bar_create();
void bar_destroy(Bar *bar);
Now you have a destructor, you just have to remember to run it when the pointer goes out of scope. If you have early returns, error handling gotos, better remember to put in all the right places and none of the wrong places. At least in this scenario you know you own the memory. If you aren't making and destroying the data structure pointer and you just get it from a function or another data structure what now? Do you destroy it or is it just a reference? What function do you use? Time to check the header file and the documentation, hopefully that exists.Not only that, but you have a pointer to the structure instead of it living on the heap. Now you have unnecessary indirection, allocation and pointer chasing when in C++ you could just treat it like a value. If you have a heap allocation in there you are now hopping from one pointer for the struct allocation to another pointer for the actual data allocation.
With your API you created an object with none of the huge advantages of being able to treat it like every other value in modern C++.
Everyone figured out how fragile this was since it started 50 years ago. Decades ago people worked out that the same problems happened constantly and came up with solutions which brought us (most of us) to where we are now.
This is not about single-build times
Now it's not about build times? I thought it was and you had said that all along? Now the story changes again.
I'm not repeating once again how this requires you to include the world for the smallest thing which is extremely painful.
Nope. You only need a class definition. Definitions don't take up any compilation time.
And "in a fraction of a second" is a ridiculous argument when it's well known that C++ single build times are spectacularly bad and developers have to wait way too much for clean rebuilds too.
People don't get themselves into bad build times because of simple class definitions. All 6MB of sqlite compiles in a single second. When people have C++ build time problems it's because of templates.
you don't do PIMPL.
I never said I did, I avoid it because that's basically what you are doing here.
Plus, PIMPL does add a runtime indirection btw
You added one already. PIMPL is the same as your indirection from heap allocating a predeclared struct so that you can return it from your constructor. The price is heap allocation and indirection.
I've said many other things.
You have, not all of them on topic.
You're a loudmouth
This is text.