C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Every variable is volatile, everything is laundered, no optimisation

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Sat, 26 Aug 2023 20:21:02 -0400
On Sat, Aug 26, 2023 at 7:07 PM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> On Sat, Aug 26, 2023 at 11:47 PM Jason McKesson wrote:
> >>
> > > But the '__verbose' marker on a function tells the compiler:
> > > "Inside the body of this function, if you detect the potential for
> > > undefined behaviour, don't take any liberties that you normally
> > > wouldn't take if such potential hadn't been detected".
> >
> > That's not a thing the standard can say.
> >
> > You don't seem to understand yet that the standard does not tell
> > compilers what to do. It's not a list of instructions about what the
> > compiler may and may not do. The standard defines behavior and
> > implementations implement the behavior as defined by the standard. The
> > standard can only constrain the behavior of an implementation by
> > *defining* what that behavior means. It cannot constrain undefined
> > behavior because... it's *undefined*.
>
>
> I get what you're saying but I think we still need to take a 'live in
> the real world' approach to this. In my previous post, the programmer
> who wrote the 'for' loop obviously intended for the loop to be broken
> out of when the integer went negative -- which will happen at some
> point if SomeFunc never returns false.

"Obviously intended"? What makes you say that? After all, if that were
the user's intent, then "obviously" they would write the C++ code that
would actually *do that*, rather than relying on UB:

```
for ( unsigned int i = 0; i < (unsigned
int)std::numeric_limits<int>::max(); ++i )
{
  if ( SomeFunc((int)i) ) break;
}

SomeFunc(-1);
}
```

Since this code not only makes it much clearer as to what is actually
going on but also has well-defined behavior, I would say that if a
programmer wrote your code, then "obviously" they did so by accident.

It should also be noted that your first example is of something that
requires UB, and this one isn't.

> Now of course, strictly
> speaking, the Standard doesn't define the behaviour of what happens
> when an int previously set to INT_MAX gets incremented, but those of
> us in the real world know that on a Two's Complement machine it will
> just become INT_MIN and there won't be any other real drama. It won't
> segfault and the CPU won't trap.

Then why not argue that it should be well-defined behavior? If this is
true of "the real world", then there shouldn't be any problem, right?
That's why the committee standardized two's complement signed integers
to begin with.

And if there's a good reason to leave overflow as UB (and yes, your
very example is exactly such a case), then it should *always* be UB.
We want users to write C++ code with well-defined behavior.

>
> I think a function marker such as '__verbose' or '__noliberties' or
> '__thorough' or '__dont_optimise' would be a good way of telling the
> compiler in a very generic sense: "Don't get on your high horse here
> about UB, stop being a princess and just do what the programmer
> obviously intended you to do".

There's that phrase again: "obviously intended".

Received on 2023-08-27 00:21:14