Date: Sun, 5 Oct 2025 20:15:31 +0200
Hi All,
While I wait for the feedback from the authors of P3835 below, let me share
a different example that puzzles me. Imagine a three-file scenario.
// lib1.hpp
// -----
bool is_calibrated(shared_ptr<Tool> const& t)
pre (t != nullptr);
// -----
// Lib2.hpp
// ----
void work(shared_ptr<Tool>& t)
pre(is_calibrated(t));
// ----
// Main.cpp
// ----
work(t);
// ----
If I somehow manage to configure my build chain to runtime-check
preconditions of the library lib2, does this mean that the assertion `t !=
nullptr` will be checked or not? The assertion as well as function
is_calibrared is defined in a different library that I am not
runtime-assertion-checking. Such a combination of preconditions seems
plausible: the author of `work()` can assume that predicates in contract
assertions can themselves have narrow contacts, and that preconditions of
preconditions apply recursively. And this is true; but it is not clear
how the selective runtime-checking enablement works in that case.
I do not think it should be left to implementations. I think the Standard
should guarantee that if an assertion predicate is evaluated using the
`enforce` mode, the preconditions of functions called in that predicate are
also evaluated in `enforce` mode. But I am not sure if this is
implementable. This gets even more interesting with `observe` mode.
Regards,
&rzej;
czw., 2 paź 2025 o 22:31 Andrzej Krzemienski <akrzemi1_at_[hidden]>
napisał(a):
>
>
> pon., 29 wrz 2025 o 22:14 John Spicer via SG21 <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;
>
>
>
While I wait for the feedback from the authors of P3835 below, let me share
a different example that puzzles me. Imagine a three-file scenario.
// lib1.hpp
// -----
bool is_calibrated(shared_ptr<Tool> const& t)
pre (t != nullptr);
// -----
// Lib2.hpp
// ----
void work(shared_ptr<Tool>& t)
pre(is_calibrated(t));
// ----
// Main.cpp
// ----
work(t);
// ----
If I somehow manage to configure my build chain to runtime-check
preconditions of the library lib2, does this mean that the assertion `t !=
nullptr` will be checked or not? The assertion as well as function
is_calibrared is defined in a different library that I am not
runtime-assertion-checking. Such a combination of preconditions seems
plausible: the author of `work()` can assume that predicates in contract
assertions can themselves have narrow contacts, and that preconditions of
preconditions apply recursively. And this is true; but it is not clear
how the selective runtime-checking enablement works in that case.
I do not think it should be left to implementations. I think the Standard
should guarantee that if an assertion predicate is evaluated using the
`enforce` mode, the preconditions of functions called in that predicate are
also evaluated in `enforce` mode. But I am not sure if this is
implementable. This gets even more interesting with `observe` mode.
Regards,
&rzej;
czw., 2 paź 2025 o 22:31 Andrzej Krzemienski <akrzemi1_at_[hidden]>
napisał(a):
>
>
> pon., 29 wrz 2025 o 22:14 John Spicer via SG21 <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;
>
>
>
Received on 2025-10-05 18:15:46