Date: Mon, 20 Oct 2025 11:08:34 -0400
On Mon, Oct 20, 2025 at 10:23 AM Ville Voutilainen <
ville.voutilainen_at_[hidden]> wrote:
> On Mon, 20 Oct 2025 at 17:18, Joshua Berne <berne_at_[hidden]> wrote:
> >
> >
> >
> > On Mon, Oct 20, 2025 at 10:12 AM Ville Voutilainen <
> ville.voutilainen_at_[hidden]> wrote:
> >>
> >> On Mon, 20 Oct 2025 at 16:58, Joshua Berne <berne_at_[hidden]>
> wrote:
> >> > 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.
> >>
> >> There's nothing in Contracts that allows for it. And then
> >> https://eel.is/c++draft/intro.compliance#general-2.1
> >> says "hi".
> >
> >
> > You are looking for something about build flags in a standard that says
> nothing about build flags.
>
> I'm not looking for build flags. I'm looking for a rule the violation
> of which allows an implementation to reject a mixed-mode program.
>
Let me try to explain where you will and won't find rules, and I do this
for the benefit of anyone that might be reading this and not for any
particular individuals whose level of understanding i have no direct
control of.
The C++ Standard, and any rule in it, applies to a platform that claims to
be a conforming implementation of that standard.
Any compiler or set of compilers can define when they do or do not
implement such a standard. Your friendly neighborhood compiler, in fact,
has a remarkably high chance fo providing build flags that explicitly say
when they do and do not implement different standards that have been
published -- gcc and clang call this `-std`, msvc uses `/std`, etc.
When a compiler or group of compilers say "invoking us this way will
produce a program that conforms to this particular C++ standard" then the
rules in the C++ standard apply and dictate what program must be produced.
If such a blessing has not been given to a particular set of compiler
invocations then it is just not a C++ implementation, and may either give
you junk, give you a program that works by chance, or give you an error
telling you that you've done something that is not supported. It's not a
C++ implementation, so the Standard does not and cannot give it permission
to produce an error in this case. This for exactly the same reason that
the standard does not have to give my toaster permission to not produce a
program when i ask it to compile my C++ program - and there is no line of
the C++ standard that gives it that permission.
Now there are certainly many cases where our existing compilers do claim
interoperability and support so that multiple compilers separated in
version, build flags, time, and space can all work together to pretend to
be a conforming C++ implementation. We have other standard and practices
around when those internal relationships allow for such conglomerations to
satisfy the requirements of being a C++ compiler, such as the itanium abi,
object file format specifications, and even machine instruction sets that
dictate how the CPU participates in this entire process of being part of a
platform.
Often, when you violate those internal rules, you get a program that is
non-conforming, such as when you mix TUs that have exception handling
disabled and those that do not. You will often get similarly unreliable
results if you mix -std flags in different TUs. Our tools vendors strive
to make these compatabilities as large as possible, but they also have full
freedom to reject attempts to mix things that they have decided not to
support.
Now implementing any such restriction is a different restriction, and there
are inumerable possibilities that can be deployed at many layers of the
toolchain, all without any need or desire for the C++ Standard to say
anything about them. We accomplish this internally with our libraries
today by coercing linkage to objects where mismatched configurations would
cause link-time errors. Compiler platforms could choose to do something
very similar if the user has asked for such restrictions.
The point i've tried to make many times, however, is that such restrictions
on mixing builds are vastly more of a problem than someone accidentally
getting a different contract-checking semantic than they one they thought
they would get. But C++26 Contracts give the toolchains ample freedom to
let users ask for such restrictions through their choice of compiler and
build flags.
ville.voutilainen_at_[hidden]> wrote:
> On Mon, 20 Oct 2025 at 17:18, Joshua Berne <berne_at_[hidden]> wrote:
> >
> >
> >
> > On Mon, Oct 20, 2025 at 10:12 AM Ville Voutilainen <
> ville.voutilainen_at_[hidden]> wrote:
> >>
> >> On Mon, 20 Oct 2025 at 16:58, Joshua Berne <berne_at_[hidden]>
> wrote:
> >> > 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.
> >>
> >> There's nothing in Contracts that allows for it. And then
> >> https://eel.is/c++draft/intro.compliance#general-2.1
> >> says "hi".
> >
> >
> > You are looking for something about build flags in a standard that says
> nothing about build flags.
>
> I'm not looking for build flags. I'm looking for a rule the violation
> of which allows an implementation to reject a mixed-mode program.
>
Let me try to explain where you will and won't find rules, and I do this
for the benefit of anyone that might be reading this and not for any
particular individuals whose level of understanding i have no direct
control of.
The C++ Standard, and any rule in it, applies to a platform that claims to
be a conforming implementation of that standard.
Any compiler or set of compilers can define when they do or do not
implement such a standard. Your friendly neighborhood compiler, in fact,
has a remarkably high chance fo providing build flags that explicitly say
when they do and do not implement different standards that have been
published -- gcc and clang call this `-std`, msvc uses `/std`, etc.
When a compiler or group of compilers say "invoking us this way will
produce a program that conforms to this particular C++ standard" then the
rules in the C++ standard apply and dictate what program must be produced.
If such a blessing has not been given to a particular set of compiler
invocations then it is just not a C++ implementation, and may either give
you junk, give you a program that works by chance, or give you an error
telling you that you've done something that is not supported. It's not a
C++ implementation, so the Standard does not and cannot give it permission
to produce an error in this case. This for exactly the same reason that
the standard does not have to give my toaster permission to not produce a
program when i ask it to compile my C++ program - and there is no line of
the C++ standard that gives it that permission.
Now there are certainly many cases where our existing compilers do claim
interoperability and support so that multiple compilers separated in
version, build flags, time, and space can all work together to pretend to
be a conforming C++ implementation. We have other standard and practices
around when those internal relationships allow for such conglomerations to
satisfy the requirements of being a C++ compiler, such as the itanium abi,
object file format specifications, and even machine instruction sets that
dictate how the CPU participates in this entire process of being part of a
platform.
Often, when you violate those internal rules, you get a program that is
non-conforming, such as when you mix TUs that have exception handling
disabled and those that do not. You will often get similarly unreliable
results if you mix -std flags in different TUs. Our tools vendors strive
to make these compatabilities as large as possible, but they also have full
freedom to reject attempts to mix things that they have decided not to
support.
Now implementing any such restriction is a different restriction, and there
are inumerable possibilities that can be deployed at many layers of the
toolchain, all without any need or desire for the C++ Standard to say
anything about them. We accomplish this internally with our libraries
today by coercing linkage to objects where mismatched configurations would
cause link-time errors. Compiler platforms could choose to do something
very similar if the user has asked for such restrictions.
The point i've tried to make many times, however, is that such restrictions
on mixing builds are vastly more of a problem than someone accidentally
getting a different contract-checking semantic than they one they thought
they would get. But C++26 Contracts give the toolchains ample freedom to
let users ask for such restrictions through their choice of compiler and
build flags.
Received on 2025-10-20 15:08:47
