C++ Logo

sg15

Advanced search

Re: [isocpp-sg15] [isocpp-sg21] P3835 -- Different contract checking for different libraries

From: Jonas Persson <Jonas.Persson_at_[hidden]>
Date: Sun, 26 Oct 2025 21:43:35 +0000
This is good. A pre<std::never_ignore || my_label>(cond)> that holds
with any type of my_label is a good start.

But there is more to this problem.

This is also a tooling issue.
With a annotated contract a compiler or analyzer can easily issue useful
diagnostics

int8_t f(uint32_t i)
   pre(i<128)
{
   if(i<128)
     return i;
}

If I used a "pre always" the tool should issue a warning "condition
always true"
If I used a "pre maybe" the tool should issue a warning "missing return"

This may seem like obvious warnings, and for the always case it is. But
for the maybe in enforce mode case an optimizer would still optimize
away both the branch and the extra return. To produce the correct
warnings it must be told that there is some configuration where the pre
is not enabled and out of contract values must be handled.

The question is then. Can we do the same with labels?

Yes sure, theoretically. But in practice there are too many
circumstances that can cause troubles. Can tools see all configurations?
Can it understand #ifdefs? Do the programmer understand all the labels?

The tool must interpret the intent of the programmer correctly. Doing
that trough labels is simply to complex and we should have the same "pre
always" and "pre maybe" as a labelless contracts. This will be a clear
declaration of intent that can be used free of misunderstanding between
programmer and tools or other human readers.

On 10/24/25 15:16, Joshua Berne via SG21 wrote:
> Ville as correct, and I want to elaborate a little because there seem
> to be misconceptions about what labels (and more specifically about
> what P3400) can and cannot do.
>
> P3400 labels provide a way to associate an object with behavior to a
> contract assertion. This can be explicitly on the assertion, but
> there are additional (higher-level and much less important)
> possibilities to apply labels in various scopes. The intent is for
> labels to be able to guide the behavior of a contract assertion by
> providing information that *is* available to the source code writer so
> that there can be collaboration with the person or persons building
> the program.
>
> There are 3 relevant facets of labels:
>
> 1. Labels can indicate that a contract assertion belongs to a
> particular (or multiple) named groups, allowing a compiler to
> collaborate to assign semantics based on the named group a contract
> assertion might belong to. I have often seen people jump to the
> conclusion that this is all that labels can do, or alternately to
> claim that this is all that we need labels to do, and both of those
> are (in my opinion) incorrect conclusions.
>
> 2. Labels can provide a function that will manipulate the evaluation
> semantic that is initially chosen (in some implementation-defined
> manner) by the compiler. This is what enables a label to *fix* the
> semantic to a specific one by simply returning the desired semantic
> and ignoring the value passed in by the platform. Such a label does
> not, however, on its own prevent combining multiple labels and getting
> a different semantic.
>
> 3. Labels provide a way to statically limit the semantics allowed by
> providing a set of allowed semantics. This limitation is not
> circumventable by the normal (operator|) mechanism to combine labels,
> so if you see a label that you know restricts assertions to only the
> enforce or quick_enforce semantics then you know that the resulting
> contract assertion will only ever be evaluated with one of those two
> semantics.
>
> There are of course other things that can be done with labels - see
> P3400 - but these are the features that are relevant to the
> particular question of "can labels guarantee that a particular
> contract will always be enforced" (yes) or "can labels let me give
> users library-scoped control over evaluation semantics" (yes, but they
> still cannot and do not attempt to "solve" the "problem" of needing to
> be in control of your build in order to be in control of your build).
>
>
> On Fri, Oct 24, 2025 at 5:23 AM Ville Voutilainen via SG21
> <sg21_at_[hidden]> wrote:
>
> We could provide standardised labels in the standard library. That
> way you don't have to guess what such labels do.
>
> pe 24. lokak. 2025 klo 12.12 Jonas Persson via SG21
> <sg21_at_[hidden]> kirjoitti:
>
> On 10/24/25 00:16, Herb Sutter via SG21 wrote:
> >
> > Summarizing: If idx is computed by the program, *and* we’re in
> > security-critical code (such as we want a
> guaranteed-hardened standard
> > library), we want this to be an assertion that is enforced in
> > production. It’s true that we can’t yet express that in C++26
> > contracts, and that the labels extension would let us express it
> > (among other things).
> >
> Labels will not solve the full problem. It may give us the
> ability to
> force a runtime assertion in production, but it does not in
> practice
> clearly separate ignorable and non-ignorable checks.
> A label can turn contracts on and off based on any kinds of
> sources
> including build flags.
> Even with labels we must be able to mark the contracts as
> guaranteed or not.
> Where guaranteed means that it will only pass if its condition
> is true,
> not because any label property.
>
> > *From:*SG21 <sg21-bounces_at_lists.isocpp.org> *On Behalf Of *Tom
> > Honermann via SG21
> > *Sent:* Thursday, October 23, 2025 9:21 AM
> > *To:* sg21_at_lists.isocpp.org; Gašper Ažman
> <gasper.azman_at_gmail.com>
> > *Cc:* Tom Honermann <tom_at_honermann.net>; Harald Achitz
> > <harald_at_[hidden]>; sg15_at_lists.isocpp.org
> > *Subject:* Re: [isocpp-sg21] [isocpp-sg15] P3835 --
> Different contract
> > checking for different libraries
> >
> > On 10/22/25 10:26 AM, John Spicer via SG21 wrote:
> >
> > That still fails to do what i want, which is to have the
> library
> > provide know that the semantic they choose will be the
> one used
> > when the program is linked.
> >
> > The following question is, again, intended as a serious one.
> >
> > Why do you want to use contracts to provide that guarantee?
> >
> > From my perspective, an unconditional-always-enforce
> contract semantic
> > changes a function that has a narrow contract into a
> function that has
> > a wide contract (or at least a wider contract subject to
> contracts
> > that are actually expressible in the language). Contracts aren't
> > needed to do that; we can express wider contracts in code
> today. Is
> > the desire based on wanting integration with a contract
> violation
> > handler? Or a desire to express hardened preconditions in
> the function
> > interface so that they are available for static analysis or
> > caller-side optimization?
> >
> > Assuming those capture your motivation, how far would
> support for a
> > syntax like the following go towards satisfying your desire?
> >
> > int* find(int *begin, int *end, int item)
> > pre *hardened* (begin != nullptr) // Hardened
> preconditions;
> > pre *hardened* (end != nullptr) // always evaluated
> with a
> > pre *hardened* (begin <= end) // terminating
> contract semantic.
> > pre (is_sorted(begin, end) // Not a hardened
> precondition.
> > ;
> >
> > It also sounds like this is mostly a variant of runtime
> semantic
> > selection, which requires the code for all possible semantic
> > varients to be emitted, which is a non-starter for most
> production
> > code.
> >
> > For what it is worth, I agree that is a non-starter for most
> > production code with the linkers and loaders in use today.
> >
> > This is a bit of a tangent, but my expectation, based on
> post link
> > optimization work I'm aware of but can't talk about, is that
> future
> > linkers and loaders will be able to support optimizing at
> load-time
> > based on a load-time selected contract semantic (similar to JIT
> > enablement of Java assertions by JVMs). I can't promise that
> such
> > technologies will ever be deployed of course or on any
> meaningful
> > timeline. I want to ensure the C++ standard does not
> prohibit use of
> > such future optimization possibilities by requiring a
> compile-time
> > selected semantic by default (I'm ok with an explicit opt-in
> as in the
> > example above).
> >
> > Tom.
> >
> > John.
> >
> >
> >
> > On Oct 20, 2025, at 7:33 AM, Gašper Ažman
> > <gasper.azman_at_[hidden]om>
> <mailto:gasper.azman_at_[hidden]> wrote:
> >
> > You can definitely do it with conventional linkers.
> You guard
> > the check with a link-time constant semantic at code
> emission;
> > you let the linker fill those in. The link-time
> constant is a
> > global that the linker deduplicates.
> >
> > You can also introduce additional labels that skip
> the checks
> > in the preconditions, and let the linker resolve the
> calls to
> > those. Normal linkers do this. It works for weak
> symbols too.
> >
> > On Mon, Oct 20, 2025 at 11:57 AM John Spicer
> > <jhspicer_at_gmail.com> wrote:
> >
> > That assumes facilities that linkers might not
> have, and
> > even if they have them, it may require expert use to
> > select the version of the function you want.
> >
> > This also potentially requires you to *know* which
> > functions you and your libraries use.
> >
> > On most systems with conventional linkers you do
> not have
> > the capability you describe.
> >
> > John.
> >
> >
> >
> > On Oct 20, 2025, at 6:52 AM, Gašper Ažman
> via SG21
> > <sg21_at_lists.isocpp.org> wrote:
> >
> > John,
> >
> > it shouldn't be "assigned randomly" - it's
> at best a
> > final link-time property (as specified). The
> final
> > link (+LTO) can do it.
> >
> > On Mon, Oct 20, 2025 at 11:50 AM John Spicer
> > <jhspicer_at_gmail.com> wrote:
> >
> > The problem is that for function
> templates, member
> > functions of class templates, and inline
> > functions, the semantic is essentially
> assigned
> > randomly if it is used in multiple TUs
> that are
> > compiled with different semantics.
> >
> > In most complex environments you are
> dealing with
> > things like libraries that are provided
> by others,
> > so you may not have control over how it
> is built.
> >
> > You can also have two libraries that use
> a third
> > library, but if those two libraries are a
> > different semantic any user of the third
> library
> > has no idea what semantic they’ll get
> even if
> > their code also uses the third library
> and is
> > built with a particular semantic.
> >
> > John.
> >
> >
> >
> > On Oct 17, 2025, at 11:45 AM, Gašper
> Ažman via
> > SG21 <sg21_at_lists.isocpp.org> wrote:
> >
> > +1 to what Tom said.
> >
> > One part of this discussion is
> speaking as if
> > semantics are assigned randomly or
> > arbitrarily, where they are assigned
> by the
> > person who ships the product - it has
> > been pointed out time and time again
> that the
> > actor deploying the application is
> the final
> > arbiter of what "safe" means for a given
> > contract check, because it's actually a
> > function of "safe(context) -> bloom"
> (where
> > "bloom" is a type with exactly two
> values of
> > "no" and "perhaps").
> >
> > The stakeholder with the best
> context is the
> > deployer of the application; the
> farther away
> > you go from that stakeholder, the
> less context
> > they have. Deferring the choice of
> semantic to
> > as late as possible gives a better
> outcome.
> >
> > On Fri, Oct 17, 2025 at 4:33 PM Tom
> Honermann
> > via SG21 <sg21_at_lists.isocpp.org> wrote:
> >
> > On Oct 17, 2025, at
> 10:23 AM, Harald
> > Achitz via SG21
> > <sg21_at_lists.isocpp.org> wrote:
> >
> > 
> >
> > On 2025-10-17 16:00, René
> Ferdinand
> > Rivera Morell wrote:
> >
> > On Fri, Oct 17, 2025 at
> 8:53 AM
> > Harald Achitz via SG15
> > <sg15_at_lists.isocpp.org>
> wrote:
> >
> > Today's
> >
> > void fun(Foo* ptr) {
> > my_supper_assert_macro
> > (ptr!=nullpter);
> > my_supper_assert_macro(ptr->hasData());
> > }
> >
> > should not have any
> problems, ever
> >
> > AFAIU, if
> my_supper_assert_macro
> > implements something
> equivalent to
> > observe, that is still UB at
> > present. Or is it EB now?
> >
> > --
> >
> > -- René Ferdinand Rivera
> Morell
> > -- Don't Assume
> Anything -- No
> > Supongas Nada
> > -- Robot Dreams -
> > http://robot-dreams.net/
> <http://robot-dreams.net/>
> >
> <http://robot-dreams.net/
> <http://robot-dreams.net/>>
> >
> > On devices that keep you
> alive, one
> > example where I have seen
> such super
> > asserts in action, contracts are
> > contracts They do not exist only
> > sometimes.
> >
> > Correct, (plain language)
> contracts are
> > omnipresent. The contract checking
> > statements above violate the
> function
> > contract and are thus defective.
> Static
> > analysis can diagnose such
> cases. For
> > example, I would expect a contracts
> > enabled version of Coverity to
> report a
> > FORWARD_NULL issue for the above
> code.
> >
> >
> > I am not even sure if
> contracts as
> > specified would pass regulatory
> > requirements, I think not.
> >
> > I’m not an expert on the subject
> by any
> > means, but I would expect regulatory
> > requirements to consider the
> manner in
> > which the software is built;
> just as they
> > consider the content of the
> source code
> > and require other supply chain
> guards. A
> > requirement that deployed
> software not
> > contain portions for which the
> observe
> > semantic is selected seems
> reasonable and
> > prudent.
> >
> > Tom.
> >
> > /Harald
> >
> > _______________________________________________
> > SG21 mailing list
> > SG21_at_lists.isocpp.org
> > Subscription:
> > https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>
> >
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>>
> > Link to this post:
> > http://lists.isocpp.org/sg21/2025/10/11351.php
> <http://lists.isocpp.org/sg21/2025/10/11351.php>
> >
> <http://lists.isocpp.org/sg21/2025/10/11351.php
> <http://lists.isocpp.org/sg21/2025/10/11351.php>>
> >
> > _______________________________________________
> > SG21 mailing list
> > SG21_at_lists.isocpp.org
> > Subscription:
> > https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>
> >
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>>
> > Link to this post:
> > http://lists.isocpp.org/sg21/2025/10/11352.php
> <http://lists.isocpp.org/sg21/2025/10/11352.php>
> >
> <http://lists.isocpp.org/sg21/2025/10/11352.php
> <http://lists.isocpp.org/sg21/2025/10/11352.php>>
> >
> > _______________________________________________
> > SG21 mailing list
> > SG21_at_lists.isocpp.org
> > Subscription:
> > https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>
> >
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>>
> > Link to this post:
> > http://lists.isocpp.org/sg21/2025/10/11422.php
> <http://lists.isocpp.org/sg21/2025/10/11422.php>
> >
> <http://lists.isocpp.org/sg21/2025/10/11422.php
> <http://lists.isocpp.org/sg21/2025/10/11422.php>>
> >
> >
> >
> > _______________________________________________
> >
> > SG21 mailing list
> >
> > SG21_at_[hidden]
> >
> >
> Subscription:https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>>
> >
> > Link to this
> post:http://lists.isocpp.org/sg21/2025/10/11687.php
> <http://lists.isocpp.org/sg21/2025/10/11687.php>
> <http://lists.isocpp.org/sg21/2025/10/11687.php
> <http://lists.isocpp.org/sg21/2025/10/11687.php>>
> >
> >
> > _______________________________________________
> > SG21 mailing list
> > SG21_at_lists.isocpp.org
> > Subscription:
> https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>
> > Link to this post:
> http://lists.isocpp.org/sg21/2025/10/11734.php
> <http://lists.isocpp.org/sg21/2025/10/11734.php>
>
>
> _______________________________________________
> SG21 mailing list
> SG21_at_[hidden].org
> Subscription:
> https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>
> Link to this post:
> http://lists.isocpp.org/sg21/2025/10/11746.php
> <http://lists.isocpp.org/sg21/2025/10/11746.php>
>
> _______________________________________________
> SG21 mailing list
> SG21_at_lists.isocpp.org
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> <https://lists.isocpp.org/mailman/listinfo.cgi/sg21>
> Link to this post: http://lists.isocpp.org/sg21/2025/10/11747.php
> <http://lists.isocpp.org/sg21/2025/10/11747.php>
>
>
> _______________________________________________
> 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/11751.php


Received on 2025-10-26 21:43:43