Date: Mon, 20 Oct 2025 09:58:40 -0400
You seem to have a vastly different experience with what the impact of
IFNDR is in practice.
In the case of odr violations, it is certainly not my experience that "your
tools will diagnose this because it is bad", it is "your tools will never
diagnose this and if you mess up ensuring you don't have odr violations in
any way then the resulting bugs will be very costly to fix". GCC"s
approach to IPO makes it clear that compilers are even actively pushing to
make previously "benign" odr violations when using assertions into sources
of UB. That is bad, and something a language feature must fix -- C++26
Contracts do.
C++26 Contracts *also* let vendors provide you an option that says "don't
let me link TUs when the TUs have different contract configurations" or
even better options like "warn me if i link builds where the same function
has been built with different contract configurations". Build
configurations are outside the standard, and platforms are completely free
to define when they do and don't work together, and to provide support for
enforcing that rule. Nothing in C++26 Contracts prohibits this possibility.
Now there is one world where odr violations are detectable reliably, and
that is a world where you deploy very expensive odr checkers that fully
understand the leeway allowed in produced binaries within the flexibility
of the odr. Such checkers have no knowledge of assertion macros, and are
thus anyone actually using defensive checking at scale must make a choice
between having any checks in their code and employing such checkers. My
experience and that conveyed to me by people at many other companies as
that this is a tradeoff where assertion macros always win, partly do to the
intractible cost of the odr checkers at scale and partly because contracts
are too useful in practice.
Contracts being a language feature gives the odr checkers a target for what
they must understand when comparing compiled functions and deciding if they
are odr violations or not --- which is why we say that C++26 Contracts
enable such tools to exist.
So C++26 Contracts have taken nothing away except the case where you make
normal use of defensive checks the same way you do today and as a reward
the compiler gives you gibberish because it can say your program is
ill-formed. The *only* negative possibility is that you thought you (the
person building the program) had built a function one way but it turns out
that you (the person building the program) also built it a different way in
a different TU and so you get the semantic from that TU. That's exactly
what we can get with linker technology today, and in the future we can both
educate people better about making bad assumptions that they are in control
of things they are not in control of and we can provide more options (in
tooling, outside the standard, and all fully conforming with C++26
Contracts) to give them the controls they want.
As others have said, what C++26 Contracts do not do is require that mixed
mode be supported in any way shape or form. We give implementations the
freedom to provide that ability, because it is abundantly clear to some of
us that not doing so will prevent any adoption of the feature. We also
give them the freedom to improve the ecosystem and toolchain to better
serve their own users.
So now I will rephrase this as I believe Mr. Voutilainen would: It frankly
astonishes me that anyone is arguing that IFNDR is a better situation than
what we provide with C++26 Contracts, because IFNDR predominantly results
in incredibly costly and challenging runtime failures, not friendly
compile-time errors or reasonable behavior.
On Mon, Oct 20, 2025 at 9:32 AM Ville Voutilainen via SG21 <
sg21_at_[hidden]> wrote:
> On Mon, 20 Oct 2025 at 16:13, Daniela Engert via SG15
> <sg15_at_[hidden]> wrote:
> >
> > I agree with the assessment, that mixing contract evaluation semantics
> introduces a problem where was none such before. While it isn't an
> (sometimes detectable) ODR violation in the token sense, it is one that is
> taking place at the very moment when the actual machine instructions are
> generated - and this is new.
>
> Right. And the end result is that we get most, maybe all, of the
> problems of ODR violations, and at the same time take away some of the
> tools
> implementation vendors have to deal with those problems.
>
> That's not "Solving the ODR problem", like P3846 and various other
> papers try to claim. It's not solving the problem at all, and it's
> making it worse.
> And in particular, P3846 has this gem in it:
> "This approach enables the use of ODR checkers and makes unsound
> optimisations that would otherwise break
> the program non-conforming."
>
> "This approach", meaning P2900, doesn't enable the use of ODR
> checkers. It disables them.
> _______________________________________________
> 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/11450.php
>
IFNDR is in practice.
In the case of odr violations, it is certainly not my experience that "your
tools will diagnose this because it is bad", it is "your tools will never
diagnose this and if you mess up ensuring you don't have odr violations in
any way then the resulting bugs will be very costly to fix". GCC"s
approach to IPO makes it clear that compilers are even actively pushing to
make previously "benign" odr violations when using assertions into sources
of UB. That is bad, and something a language feature must fix -- C++26
Contracts do.
C++26 Contracts *also* let vendors provide you an option that says "don't
let me link TUs when the TUs have different contract configurations" or
even better options like "warn me if i link builds where the same function
has been built with different contract configurations". Build
configurations are outside the standard, and platforms are completely free
to define when they do and don't work together, and to provide support for
enforcing that rule. Nothing in C++26 Contracts prohibits this possibility.
Now there is one world where odr violations are detectable reliably, and
that is a world where you deploy very expensive odr checkers that fully
understand the leeway allowed in produced binaries within the flexibility
of the odr. Such checkers have no knowledge of assertion macros, and are
thus anyone actually using defensive checking at scale must make a choice
between having any checks in their code and employing such checkers. My
experience and that conveyed to me by people at many other companies as
that this is a tradeoff where assertion macros always win, partly do to the
intractible cost of the odr checkers at scale and partly because contracts
are too useful in practice.
Contracts being a language feature gives the odr checkers a target for what
they must understand when comparing compiled functions and deciding if they
are odr violations or not --- which is why we say that C++26 Contracts
enable such tools to exist.
So C++26 Contracts have taken nothing away except the case where you make
normal use of defensive checks the same way you do today and as a reward
the compiler gives you gibberish because it can say your program is
ill-formed. The *only* negative possibility is that you thought you (the
person building the program) had built a function one way but it turns out
that you (the person building the program) also built it a different way in
a different TU and so you get the semantic from that TU. That's exactly
what we can get with linker technology today, and in the future we can both
educate people better about making bad assumptions that they are in control
of things they are not in control of and we can provide more options (in
tooling, outside the standard, and all fully conforming with C++26
Contracts) to give them the controls they want.
As others have said, what C++26 Contracts do not do is require that mixed
mode be supported in any way shape or form. We give implementations the
freedom to provide that ability, because it is abundantly clear to some of
us that not doing so will prevent any adoption of the feature. We also
give them the freedom to improve the ecosystem and toolchain to better
serve their own users.
So now I will rephrase this as I believe Mr. Voutilainen would: It frankly
astonishes me that anyone is arguing that IFNDR is a better situation than
what we provide with C++26 Contracts, because IFNDR predominantly results
in incredibly costly and challenging runtime failures, not friendly
compile-time errors or reasonable behavior.
On Mon, Oct 20, 2025 at 9:32 AM Ville Voutilainen via SG21 <
sg21_at_[hidden]> wrote:
> On Mon, 20 Oct 2025 at 16:13, Daniela Engert via SG15
> <sg15_at_[hidden]> wrote:
> >
> > I agree with the assessment, that mixing contract evaluation semantics
> introduces a problem where was none such before. While it isn't an
> (sometimes detectable) ODR violation in the token sense, it is one that is
> taking place at the very moment when the actual machine instructions are
> generated - and this is new.
>
> Right. And the end result is that we get most, maybe all, of the
> problems of ODR violations, and at the same time take away some of the
> tools
> implementation vendors have to deal with those problems.
>
> That's not "Solving the ODR problem", like P3846 and various other
> papers try to claim. It's not solving the problem at all, and it's
> making it worse.
> And in particular, P3846 has this gem in it:
> "This approach enables the use of ODR checkers and makes unsound
> optimisations that would otherwise break
> the program non-conforming."
>
> "This approach", meaning P2900, doesn't enable the use of ODR
> checkers. It disables them.
> _______________________________________________
> 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/11450.php
>
Received on 2025-10-20 13:58:54
