Date: Tue, 14 Oct 2025 06:21:36 -0400
You say "even if P2900 does not fix linking issues that are not inherent to Contracts”, but the point of P3835 is that the issues *are* inherent to contracts.
The reason for this is that if you currently use a macro like MY_LIB_ASSERT(x), then you have control over what it does, even when your header is used by someone else. If you fail to get this right, it is an ODR violation. So you have done something that makes your program ill-formed, and your tools might be able to detect this.
But if you use contracts, it is not an ODR violation, even when the functions end up doing different things.
So, contracts introduce a new problem that other mechanisms, including C assert, do not have.
John.
> On Oct 13, 2025, at 5:21 PM, Ryan McDougall via SG21 <sg21_at_[hidden]> wrote:
>
> Let's be very specific with our words -- "okay" and "safe" are not well defined terms with which we can make sound engineering decisions.
>
> I did not claim that programs which may have UB are "okay" -- I'm saying that for decades we have made programs that may have UB to be made "Functionally Safe"" -- because "Functional Safety" does not depend on language guarantees. As p3578r1 <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3578r1.pdf> explains, we got humans to the moon with assembly language. "Functional Safe" depends on Assurance -- ie. highly rigorous and structured testing.
>
> While contracts can *help* Language Safety, Contracts do not need to be "Language Safe". Complaints that contracts are not "Language Safe" are misplaced. Contracts are a strict improvement for "Functional Safety" and that's justification enough -- even if P2900 does not fix linking issues that are not inherent to Contracts.
>
> On Mon, Oct 13, 2025 at 1:20 PM John Spicer via SG15 <sg15_at_[hidden] <mailto:sg15_at_[hidden]>> wrote:
>> I certainly hold Ryan in high regard, but I don’t understand how the situation described in P3835 can be considered “okay”.
>>
>> As P3835 says, the library with l1.cpp is built with the quick_enforce semantic. c1.cpp is compiled with the ignore semantic.
>>
>> If the line in red is removed, the program will fail the assertion. If the line in red is present, the program might not fail the assertion.
>>
>> Maybe Ryan and you are okay with that behavior.
>>
>> I’m not.
>>
>> John.
>>
>> file: z.h
>>
>> inline void f(int x) {
>> contract_assert(x > 0);
>> }
>>
>> file: l1.cpp
>>
>> #include "z.h"
>>
>> void g() {
>> f(0); // expected to fail contract
>> }
>>
>> file: c1.cpp
>>
>> #include "z.h"
>>
>> extern void g();
>>
>> int main() {
>> f(1); // expected to pass contract
>> g();
>> }
>>
>>
>>> On Oct 13, 2025, at 2:48 PM, Gideon Mueller via SG21 <sg21_at_[hidden] <mailto:sg21_at_[hidden]>> wrote:
>>>
>>> 100% agree with what Ryan wrote!
>>>
>>> I fail to see how “the problem” stated in P3835 is specific to contracts and why a contracts /MVP/ should be considered responsible for solving it. If it got covered in the email thread I missed it, could the authors please expand on this or point to where they did?
>>>
>>> PS: maybe the issue is on my end, but I am unable to access https://contracts.efcs.ca/#contract-groups, does anyone have an alternative link?
>>>
>>> Regards
>>> Gideon
>>>
>>> From: SG21 <sg21-bounces_at_[hidden] <mailto:sg21-bounces_at_[hidden]>> on behalf of Ryan McDougall via SG21 <sg21_at_[hidden] <mailto:sg21_at_[hidden]>>
>>> Date: Sunday, 5. October 2025 at 21:01
>>> To: sg15_at_[hidden] <mailto:sg15_at_[hidden]> <sg15_at_[hidden] <mailto:sg15_at_[hidden]>>
>>> Cc: Ryan McDougall <mcdougall.ryan_at_[hidden] <mailto:mcdougall.ryan_at_[hidden]>>, SG21 Contracts <sg21_at_[hidden] <mailto:sg21_at_[hidden]>>
>>> Subject: Re: [isocpp-sg21] [isocpp-sg15] P3835 -- Different contract checking for different libraries
>>>
>>> External email: Use caution opening links or attachments
>>>
>>> I'm always disappointed with phrasing like "is not safe" or "not viable in the real world", because invariably the speakers do not show a working definition of "safe" and lack experience in safety critical software -- this puts the burden of education on one side, which ends up in volumes of pages that are simply never read.
>>>
>>> They most certainly haven't read P3297 C++26 Needs Contract Checking <https://wg21.link/p3297> -- which was approved by SG23 in St Louis -- nor P3578 What is "Safety"? <https://isocpp.org/files/papers/P3578R1.pdf> which actually defines the "safety" with precision and clarity. We have been talking about this since P1517 Contract Requirements for Iterative High-Assurance Systems <http://wg21.link/p1517>.
>>>
>>> P2900 is "Safe", according to P3578 -- which itself follows decades of industry practice -- and is the reason you arrive at WG21 meetings alive. P2900 is "viable", because the industry has been using macro-based checks in our software since before most of us were programmers. To say the contrary is simply not sustainable.
>>>
>>> If you want to have different checks on different "components", then this is a matter of library design -- something we've been doing for decades: compile the TUs you want with semantic X into a static library, and semantic Y into another static library, and then link the two together. Software design -- done.
>>>
>>> P2900 is the result of one of the most rigorous design processes I've ever witnessed at WG21, and P2900 is intended to be a minimum viable product that adheres to a collection of use cases laid out in P1995 Contract Use <http://wg21.link/p1995> cases from 2020. It has been derided as both not minimal enough, and overly complicated -- yet no one bothers to do a counter analysis to come to different conclusions. There are reams of pages in the papers that lead to P2900, but the pagers in the papers running counter are scant, hand-wavy, and abuse decades of industry standard jargon.
>>>
>>> P2900 is safe, and is viable -- and no one has yet presented a serious argument to the contrary.
>>>
>>> Cheers,
>>>
>>> On Thu, Oct 2, 2025 at 1:31 PM Andrzej Krzemienski via SG15 <sg15_at_[hidden] <mailto:sg15_at_[hidden]>> wrote:
>>>
>>>
>>> pon., 29 wrz 2025 o 22:14 John Spicer via SG21 <sg21_at_[hidden] <mailto:sg21_at_[hidden]>> napisał(a):
>>> I think that compile-time and link-time selection of semantics is a desirable feature.
>>>
>>> But that misses the essential point of p3835r0 that the semantics need to apply to software “components” and not to translation units or to the entire program.
>>>
>>> If you consider the example in the paper I referenced, it is essential that the check in l1.cpp fail.
>>>
>>> There could be some other contract check in c1.cpp that is expected to be ignored.
>>>
>>> The key issue is not, IMO, how you control a “checking mode” that applies to a TU or the program, the issue is how you apply various “checking modes” to different components (e.g., libraries).
>>>
>>> There are a number of possible solutions to this problem, each of which have their own tradeoffs.
>>>
>>> But the first step is the recognition that this is a problem that needs to be solved in order for contracts to be viable in the real world.
>>>
>>> I would like to understand this expectation a bit more. Rather than talking about the details I would focus on the motivation.
>>>
>>> The scenario that I am familiar with is that when a program P uses a library L, it is likely that P will use L incorrectly, and additional measures need to be taken to test if P is using L correctly. This would mean that in the P2900 world we would want to runtime check the assertions *at the library boundary* but not necessarily *inside* the library. IOW, If I were the author of P, I would trust library L that it was thoroughly tested, and would not want to assertion-test its implementation. But I would like to test if I am *using* the library correctly. So I would like to enable every precondition in L's interface and some contract_asset statements close to library entry points that also function as preconditions. But only those. If libstdc++'s STL implementation offers control macros to enable STL-specific assertions, those assertions practically check if the user is using the STL correctly: not if STL has been correctly implemented.
>>>
>>> But P3835 seems to be expressing a different need. So my question to the authors of P3835 is: is your motivating use case testing the library *usage* or really testing one library's implementation in a different way than another library's implementation? If it is the latter, that would be strange: you would have to mistrust the library L enough to want to keep checking its implementation, but at the same time trust it enough that the author put the right assertions in the right places with sufficient density.
>>>
>>> Regards,
>>> &rzej;
>>>
>>>
>>> _______________________________________________
>>> SG15 mailing list
>>> SG15_at_[hidden] <mailto:SG15_at_[hidden]>
>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
>>> _______________________________________________
>>> SG21 mailing list
>>> SG21_at_[hidden] <mailto:SG21_at_[hidden]>
>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sg21
>>> Link to this post: http://lists.isocpp.org/sg21/2025/10/11233.php
>>
>> _______________________________________________
>> SG15 mailing list
>> SG15_at_[hidden] <mailto:SG15_at_[hidden]>
>> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
> _______________________________________________
> SG21 mailing list
> SG21_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> Link to this post: http://lists.isocpp.org/sg21/2025/10/11237.php
The reason for this is that if you currently use a macro like MY_LIB_ASSERT(x), then you have control over what it does, even when your header is used by someone else. If you fail to get this right, it is an ODR violation. So you have done something that makes your program ill-formed, and your tools might be able to detect this.
But if you use contracts, it is not an ODR violation, even when the functions end up doing different things.
So, contracts introduce a new problem that other mechanisms, including C assert, do not have.
John.
> On Oct 13, 2025, at 5:21 PM, Ryan McDougall via SG21 <sg21_at_[hidden]> wrote:
>
> Let's be very specific with our words -- "okay" and "safe" are not well defined terms with which we can make sound engineering decisions.
>
> I did not claim that programs which may have UB are "okay" -- I'm saying that for decades we have made programs that may have UB to be made "Functionally Safe"" -- because "Functional Safety" does not depend on language guarantees. As p3578r1 <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3578r1.pdf> explains, we got humans to the moon with assembly language. "Functional Safe" depends on Assurance -- ie. highly rigorous and structured testing.
>
> While contracts can *help* Language Safety, Contracts do not need to be "Language Safe". Complaints that contracts are not "Language Safe" are misplaced. Contracts are a strict improvement for "Functional Safety" and that's justification enough -- even if P2900 does not fix linking issues that are not inherent to Contracts.
>
> On Mon, Oct 13, 2025 at 1:20 PM John Spicer via SG15 <sg15_at_[hidden] <mailto:sg15_at_[hidden]>> wrote:
>> I certainly hold Ryan in high regard, but I don’t understand how the situation described in P3835 can be considered “okay”.
>>
>> As P3835 says, the library with l1.cpp is built with the quick_enforce semantic. c1.cpp is compiled with the ignore semantic.
>>
>> If the line in red is removed, the program will fail the assertion. If the line in red is present, the program might not fail the assertion.
>>
>> Maybe Ryan and you are okay with that behavior.
>>
>> I’m not.
>>
>> John.
>>
>> file: z.h
>>
>> inline void f(int x) {
>> contract_assert(x > 0);
>> }
>>
>> file: l1.cpp
>>
>> #include "z.h"
>>
>> void g() {
>> f(0); // expected to fail contract
>> }
>>
>> file: c1.cpp
>>
>> #include "z.h"
>>
>> extern void g();
>>
>> int main() {
>> f(1); // expected to pass contract
>> g();
>> }
>>
>>
>>> On Oct 13, 2025, at 2:48 PM, Gideon Mueller via SG21 <sg21_at_[hidden] <mailto:sg21_at_[hidden]>> wrote:
>>>
>>> 100% agree with what Ryan wrote!
>>>
>>> I fail to see how “the problem” stated in P3835 is specific to contracts and why a contracts /MVP/ should be considered responsible for solving it. If it got covered in the email thread I missed it, could the authors please expand on this or point to where they did?
>>>
>>> PS: maybe the issue is on my end, but I am unable to access https://contracts.efcs.ca/#contract-groups, does anyone have an alternative link?
>>>
>>> Regards
>>> Gideon
>>>
>>> From: SG21 <sg21-bounces_at_[hidden] <mailto:sg21-bounces_at_[hidden]>> on behalf of Ryan McDougall via SG21 <sg21_at_[hidden] <mailto:sg21_at_[hidden]>>
>>> Date: Sunday, 5. October 2025 at 21:01
>>> To: sg15_at_[hidden] <mailto:sg15_at_[hidden]> <sg15_at_[hidden] <mailto:sg15_at_[hidden]>>
>>> Cc: Ryan McDougall <mcdougall.ryan_at_[hidden] <mailto:mcdougall.ryan_at_[hidden]>>, SG21 Contracts <sg21_at_[hidden] <mailto:sg21_at_[hidden]>>
>>> Subject: Re: [isocpp-sg21] [isocpp-sg15] P3835 -- Different contract checking for different libraries
>>>
>>> External email: Use caution opening links or attachments
>>>
>>> I'm always disappointed with phrasing like "is not safe" or "not viable in the real world", because invariably the speakers do not show a working definition of "safe" and lack experience in safety critical software -- this puts the burden of education on one side, which ends up in volumes of pages that are simply never read.
>>>
>>> They most certainly haven't read P3297 C++26 Needs Contract Checking <https://wg21.link/p3297> -- which was approved by SG23 in St Louis -- nor P3578 What is "Safety"? <https://isocpp.org/files/papers/P3578R1.pdf> which actually defines the "safety" with precision and clarity. We have been talking about this since P1517 Contract Requirements for Iterative High-Assurance Systems <http://wg21.link/p1517>.
>>>
>>> P2900 is "Safe", according to P3578 -- which itself follows decades of industry practice -- and is the reason you arrive at WG21 meetings alive. P2900 is "viable", because the industry has been using macro-based checks in our software since before most of us were programmers. To say the contrary is simply not sustainable.
>>>
>>> If you want to have different checks on different "components", then this is a matter of library design -- something we've been doing for decades: compile the TUs you want with semantic X into a static library, and semantic Y into another static library, and then link the two together. Software design -- done.
>>>
>>> P2900 is the result of one of the most rigorous design processes I've ever witnessed at WG21, and P2900 is intended to be a minimum viable product that adheres to a collection of use cases laid out in P1995 Contract Use <http://wg21.link/p1995> cases from 2020. It has been derided as both not minimal enough, and overly complicated -- yet no one bothers to do a counter analysis to come to different conclusions. There are reams of pages in the papers that lead to P2900, but the pagers in the papers running counter are scant, hand-wavy, and abuse decades of industry standard jargon.
>>>
>>> P2900 is safe, and is viable -- and no one has yet presented a serious argument to the contrary.
>>>
>>> Cheers,
>>>
>>> On Thu, Oct 2, 2025 at 1:31 PM Andrzej Krzemienski via SG15 <sg15_at_[hidden] <mailto:sg15_at_[hidden]>> wrote:
>>>
>>>
>>> pon., 29 wrz 2025 o 22:14 John Spicer via SG21 <sg21_at_[hidden] <mailto:sg21_at_[hidden]>> napisał(a):
>>> I think that compile-time and link-time selection of semantics is a desirable feature.
>>>
>>> But that misses the essential point of p3835r0 that the semantics need to apply to software “components” and not to translation units or to the entire program.
>>>
>>> If you consider the example in the paper I referenced, it is essential that the check in l1.cpp fail.
>>>
>>> There could be some other contract check in c1.cpp that is expected to be ignored.
>>>
>>> The key issue is not, IMO, how you control a “checking mode” that applies to a TU or the program, the issue is how you apply various “checking modes” to different components (e.g., libraries).
>>>
>>> There are a number of possible solutions to this problem, each of which have their own tradeoffs.
>>>
>>> But the first step is the recognition that this is a problem that needs to be solved in order for contracts to be viable in the real world.
>>>
>>> I would like to understand this expectation a bit more. Rather than talking about the details I would focus on the motivation.
>>>
>>> The scenario that I am familiar with is that when a program P uses a library L, it is likely that P will use L incorrectly, and additional measures need to be taken to test if P is using L correctly. This would mean that in the P2900 world we would want to runtime check the assertions *at the library boundary* but not necessarily *inside* the library. IOW, If I were the author of P, I would trust library L that it was thoroughly tested, and would not want to assertion-test its implementation. But I would like to test if I am *using* the library correctly. So I would like to enable every precondition in L's interface and some contract_asset statements close to library entry points that also function as preconditions. But only those. If libstdc++'s STL implementation offers control macros to enable STL-specific assertions, those assertions practically check if the user is using the STL correctly: not if STL has been correctly implemented.
>>>
>>> But P3835 seems to be expressing a different need. So my question to the authors of P3835 is: is your motivating use case testing the library *usage* or really testing one library's implementation in a different way than another library's implementation? If it is the latter, that would be strange: you would have to mistrust the library L enough to want to keep checking its implementation, but at the same time trust it enough that the author put the right assertions in the right places with sufficient density.
>>>
>>> Regards,
>>> &rzej;
>>>
>>>
>>> _______________________________________________
>>> SG15 mailing list
>>> SG15_at_[hidden] <mailto:SG15_at_[hidden]>
>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
>>> _______________________________________________
>>> SG21 mailing list
>>> SG21_at_[hidden] <mailto:SG21_at_[hidden]>
>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sg21
>>> Link to this post: http://lists.isocpp.org/sg21/2025/10/11233.php
>>
>> _______________________________________________
>> SG15 mailing list
>> SG15_at_[hidden] <mailto:SG15_at_[hidden]>
>> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
> _______________________________________________
> SG21 mailing list
> SG21_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> Link to this post: http://lists.isocpp.org/sg21/2025/10/11237.php
Received on 2025-10-14 10:21:51
