3 ms·
> More insults but there is no difference here. Rebutting your wild and easily disproved claims where it's necessary. > I looked at your godbolt link, which p
by jstimpfle 3mo ago
> More insults but there is no difference here.
Rebutting your wild and easily disproved claims where it's necessary.
> I looked at your godbolt link, which part of this does C avoid?
Should I spell it out again for you? With non-class programming, you can do
struct Foo;
struct Bar;
Bar *bar_create();
void bar_destroy(Bar *bar);
void foo_doThing(Foo *foo);
Foo *foo_create(int x, int y, Bar *bar);
void foo_destroy(Foo *foo);
And that's literally the API, clean and readable. Now granted, it doesn't do RAII, but here's the essence of the API, in a form that you can actually improve and develop and refactor, and which doesn't require you to rebuild the world if you changed something in a remote corner of the codebase.
This is super well known common lore, and if you haven't noticed this yourself and haven't heard many people talking about this, you simply don't know what you're talking about.
> Every struct and class definition you have ever written compiles in a fraction of a second on hardware from 15 years ago this makes no sense at all.
I'm not repeating once again how this requires you to include the world for the smallest thing which is extremely painful.
> Is it your argument against an optional feature seriously that you can't use the PIMPL pattern from the 90s ? Holy mother of god, that's what is so important? Every struct and class definition you have ever written compiles in a fraction of a second on hardware from 15 years ago this makes no sense at all. It even took you an entire novel of "nu uh" and "this program was written in C so everything else is bad" to get there.
This is not about single-build times (which are much more affected by by template metaprogramming), but about quadratic incremental rebuild scaling. 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.
You just don't get it. And no, you don't do PIMPL. It doesn't scale at all. It's realistic to PIMPL a plain struct once in a while, but NOT with C++ classes with methods etc on a regular basis. It's not ergonomic to do so, it requires even much more boilerplate to do the simplest thing, and it makes it incredibly hard to change and fix and evolve anything. Plus, PIMPL does add a runtime indirection btw. It's BAD.
Again, I know what I'm talking down not because I'm repeating what "my heroes" said but because I've actually tried to make it work, many times. It doesn't work. And you're not doing PIMPL either. Want to know how I know? BECAUSE IT DOESN'T WORK AND YOU ARE JUST TALKING.
> Now it boils down to something that is no different but without it all the same memory bugs persist.
You can't be serious. Now you claim that's the only thing I said? No, I've said many other things. You're a loudmouth who doesn't understand the most basic thing, so we have to spend days before you accept the tiniest straightforward common sense argument that you could just google. Do you want to go down the next rabbit hole? Because I don't, I'm so done with you.
- CyberDildonics 3mo agoBar *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.
- jstimpfle 3mo agoIt's long been clear that you don't understand what you're talking about when you're criticizing what I say. You don't realize that I understand everything you say and I'm only explaining where your line of reasoning breaks. The concerns you raise are beginner level C++ object thinking. You still haven't understood what I've said. It has turned out that the actual zealot is you, you're just a follower of mainstream ideology, following conventions without understanding them. Being part of the mainstream seems to mean you feel legitimized to talk down on others who are looking for solutions to genuine, serious problems. Following the mainstream will give you predictable results, but also with a low ceiling of what you can achieve this way. > Nope. You only need a class definition. How hard is it to understand that to get a class definition, all the stuff that's used inside the class, including declarations of internals like private fields and methods, needs to be included first? How hard is it? It seems like you are terminally unable to see it. Have you never touched a seemingly unimportant header file and had to rebuild 80% of your project? Because that's the common case in most real world C++ projects (and also some badly designed C projects btw.), in my experience. > Now it's not about build times? I thought it was and you had said that all along? Now the story changes again. Are you insane, you first critized me for making too many different points, then later you claimed I had NEVER talked about build times, which I refuted with a simple Ctrl+F argument. Then later you critized me for talking ONLY about build times. Now you critize me again for talking about a variety of things? While I have stressed from the beginning that I'm talking about systemic problems, which manifest in lots of ways. Maybe Ctrl+F for "and here are a million examples why" for example? You are a weasel with no purpose other than talking down on me, and you haven't made a single interesting argument. Get lost. > All 6MB of sqlite compiles in a single second Sure, a while ago, I even compiled it in 300ms using tcc (as a test). Do you know why that works? Because sqlite is written in C, without insane C++ classes and features. They compile everything as a single file (like raddebugger does too btw., a legitimate approach but I'm not saying this is the solution for everyone), circumventing the quadratic translation unit scaling problem. > 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. A PIMPL object is one that is referenced as a pointer (of void-type or forward declared type) in a struct trying to protect implementation details and dependencies, because C++ doesn't exactly want you to do that. The price of an actual C++ PIMPL object is that you'll go insane duplicating all the methods and writing all the call forwards. This is NOTHING like a forward declared C struct, which is the exact opposite. There is NO duplication and call forwarding. You haven't got a clue what you're talking about. A forward declared C struct does not add another level of indirection. You can't put the object itself directly on the stack unless you know the struct definition, that is obvious. It's the price to pay for true abstraction, abstracting from the internals of the object and treating it uniformly as a pointer value. But that's not a problem at all, since you would never want to put abstracted objects on the stack. Putting objects on the stack is how you write tiny scripty toy applications. In systems programming, object lifetimes don't correlate to function call lifetimes, so you cannot put objects on the stack. If you are able to put most of your objects on the stack by value, you are working on a toy app. Contrast objects here with plain structs, for example struct Float3 { float x, y, z; }. Of course you expose those as values, these are stateless objects. And putting them on the stack is fine. That has nothing to do with PIMPL or implementation hiding AT ALL. > 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++. There is no "like every other value" in C++, regardless of how hard people are trying, and regardless of how much complexity these people pile on top of this language. The only successful "every other value" is plain data, which you can simply copy as bytes. I could queue a lecture now why Unix was successful with its file concept of "raw bag of bytes", but I'm done with you. Good bye.