C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Public inheritance with banned conversion to base

From: organicoman <organicoman_at_[hidden]>
Date: Sun, 26 Jan 2025 19:58:03 +0100
Arthur,Your $.02 worths gold 👍🏻That's how we should explain. Sent from my Galaxy
-------- Original message --------From: Arthur O'Dwyer via Std-Proposals <std-proposals_at_[hidden]> Date: 1/26/25 6:37 PM (GMT+01:00) To: std-proposals_at_[hidden] Cc: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> Subject: Re: [std-proposals] Public inheritance with banned conversion to base On Sun, Jan 26, 2025 at 11:43 AM Thiago Macieira via Std-Proposals <std-proposals_at_[hidden]> wrote:On Friday 24 January 2025 14:45:58 Pacific Standard Time Arthur O'Dwyer via
Std-Proposals wrote:
> (3) more stable in case this is a long-lived
> shared-library ABI boundary.

That is a non-goal. If the standard libraries change the mangling, it's
usually for a good reason and it's going to be something you *do* want to have
reflected in your ABI. Trying to force a name such that mangled names remain
while the structure changed incompatibly is going to lead to hard-to-diagnose
bugs.Let (A) be the client-programmer code: using MyVec = std::vector<int>;and (B) be the client-programmer code: struct MyVec; [...] struct MyVec : std::vector<int> {};Let some client-programmer code using these definitions be compiled into two different TUs — "library.so" which is then fixed/frozen/unmodifiable, and "user.cpp", which will be recompiled later.Then, let (1) be the scenario where the STL vendor changes the mangling of `std::vector` without changing its behavior (e.g. by adding or removing a nested `inline namespace`).Let (2) be the scenario where the STL vendor changes the behavior of `std::vector` without changing its mangling (e.g. by replacing pointer+length with pointer+pointer, or vice versa).In situation (A+1), we get a linker error, because `MyVec` in "user.cpp" now mangles differently from how it did at the time "library.so" was compiled. We cannot fix it except by reintroducing the old mangling for `std::vector` into "user.cpp".In situation (A+2), we get UB at runtime. We cannot fix it except by reintroducing the old behavior into "user.cpp" under the name `std::vector`.In situation (A+1+2), we get a linker error. We cannot fix it except by reintroducing the old behavior into "user.cpp" under the old mangling for `std::vector`.In situation (B+1), everything works fine.In situation (B+2), we get UB at runtime. We can fix it by eliminating `MyVec`'s inheritance from `std::vector` and reimplementing it, in "user.cpp", according to its old behavior.In situation (B+1+2), we get UB at runtime. We can fix it by eliminating `MyVec`'s inheritance from `std::vector` and reimplementing it, in "user.cpp", according to its old behavior.The fixes in cases (A+1) and (A+2) involve the client-programmer messing around with namespace `std`.The fix in case (B+2) involves the client-programmer messing around only with the definition of their own `MyVec`.So I think approach (B) has certain advantages in practice. It's not clearly better in every way — in particular, the build system will flag the problem in situation (A+1+2) but cause silent UB in situation (B+1+2). But if you already know that you're in situation (1+2) and are tasked with fixing it, I think I'd rather start from (B+1+2) than from (A+1+2).my $.02,–Arthur

Received on 2025-01-26 18:58:14