| No, but that's also not relevant as C++ is ABI stable. I can take any C++ compiler, and I can compile any C++ library, and then I can take some other compiler and compile some other piece of C++ that calls my library, and it will Just Work. I can then go back to my library, and make a bunch of ABI safe changes, just as I would have to do in C, and compile my library again, with yet another compiler. At that point the program that was using the older version of my library, would continue to work with the new build of my library without needing to be recompiled. This is because C++ is ABI stable. If I am in C++, and I make an ABI breaking change to something that is used as a base class elsewhere, then I have broken the ABI. But this problem also exists in C, for exactly the same reason, for example lets make some silly example C If I am a C library, and my header declares a struct struct AwesomeThing {
intptr_t foo;
};
void doSomething(struct AwesomeThing* thing) {
thing->foo = 0;
}
And then someone uses my library in their code: struct ImAwesomeToo {
struct AwesomeThing theAwesomest;
int* thisFieldIsGreat;
};
int doSomethingElse() {
struct ImAwesomeToo thing;
thing.thisFieldIsGreat = malloc(sizeof(int));
doSomething(&thing.theAwesomest);
free(thing.thisFieldIsGreat);
}
Obviously this is a somewhat silly example, but now say I make a change to my library: struct AwesomeThing {
intptr_t foo;
double bar;
}
void doSomething(struct AwesomeThing* thing) {
thing->bar = 42;
}
By the standard rules I haven't "broken" ABI, but now that call to free() is going to cause problems.That's the fragile base class problem. If you are making an API that will have ABI stability requirements you have to expend quite a bit of effort designing the API so it's not only pleasant to use, but also can be evolved without breaking the ABI. As with C APIs, the people who make C++ APIs, know how to make them robust as well. That said you could have a C or C++ ABI that is ABI stable, it just hurts performance, and obviously adopting that would break ABI :D Anyway, the problem with what rust and co are saying, is that the same source can result in different ABIs from one compiler version to the next, or for one API to compile to a different ABI depending on what the rest of the code in the project is doing. That means the OS can't use the safe language as an actual OS API, which I just think is wasting an opportunity. Swift manages, and ostensibly performs the same kind of optimizations within a module, which is most of what you want. That said because it's the system API all objects are refcounted, and the recount is atomic - I was writing a raytracer in it (this is how I learn programming languages) and the refcount overhead was annoying to deal with. Obviously there are trade offs in all the choices, but I still feel like rust, etc could do more. Rust has rich support for annotations, so an "abi_stable" annotation seems like it would be perfectly reasonable - it would be in keeping with rust's general theme of the default behaviour not having any implicit performance costs, but would be easy and very clear when you were making something into an API. |
It seems too optimistic for me. I use Gentoo, and I believe that the only reason I have no such troubles is Gentoo with all its maintainers who do a great work of testing different combinations of libraries. And of course `ebuild` that can rebuild libc.so without breaking the system. I tried it once when I just started with linux, and I failed. Never tried to do it again myself, I let `ebuild` do it. It is not so easy, you know, to change version of a library which is a dependency of every binary in the system. And it is a C library. I wouldn't even try to do it, if it was a C++ library. Though who knows, two decades ago when I started with linux I probably was dumb enough to try.