C++ Logo

SG14

Advanced search

Subject: Re: [isocpp-parallel] (SC22WG14.16350) Rough notes from SC22 WG21 SG14 meeting on pointer lifetime-end zap
From: Hans Boehm (boehm_at_[hidden])
Date: 2019-05-03 12:17:15


Indeed. And even with my lack of clang expertise, it's clear that this
would be highly nontrivial to change in clang and probably some other
compilers. It's clearly not a change that we should make lightly. On the
other hand, that also makes it more urgent to address the issue, since
compilers currently still seem to stop short of applying the rule in
situations where it would interfere with real code.

I would personally still favor a more usable and intuitive model in the
long term over implementer inconvenience in the short term. Implementations
are easier to change than client code. The compiler problems are hard, but
coming up with alternative parallel algorithms, or teaching tens of
millions of programmers a needlessly complex rule, is almost certainly
harder.

This seems to be a case where we currently have an unintuitive rule (at
least to most people) that introduces UB that seriously gets in the way of
applications (and in my opinion teaching), without a fully convincing
argument to justify the rule. Especially given the general complaints about
UB in C and C++, I think we should avoid such cases. I'm perfectly willing
to accept UB in other cases, like signed integer overflow, where it gives
useful implementation freedom and demonstrably helps optimizers. Here I
think we basically have an unproven conjecture that it might eventually do
the former (via potentially making use-after-free easier to detect) and
some really obscure, and to me unconvincing, examples of the latter.

My conjecture (real information welcome!) is that current compilers tend to
conflate compiler optimization facts like "*a aliases *b" or "a and b point
to the same thing" with the result of the expression "a == b". The current
standard sanctions this, but fundamentally they're not the same. When the
compiler asks aliasing questions, it generally wants to know whether an
update through one pointer could affect the value pointed to by the other.
It doesn't care what answer it gets if either side cannot be safely
dereferenced. We now have lots of examples where user code does care about
that case.

On Fri, May 3, 2019 at 1:50 AM Niall Douglas <s_sourceforge_at_[hidden]>
wrote:

> >>> T *a = new T;
> >>> delete a;
> >>> T *b = new T;
> >>>
> >>> // Everybody agrees the compiler can assume this is always true
> >>> assert(a != b);
> >> I'm not at all sure this is right. The compiler can definitely assume
> that
> >> *a and *b do not alias; falsifying that would involve dereferences which
> >> would result in undefined behavior. And disallowing that assumption
> would
> >> slow down code. But that's not really exposed to the user, and not the
> same
> >> thing as claiming a!=b is true.
> >
> > y
>
> As I already explained with code snippets in previous emails, clang
> already hard assumes the above comparison is always true. I'll relink my
> godbolt example: https://godbolt.org/z/c219s9
>
> This is because, as Richard Smith already explained, clang already does
> provenance tracking, and its rules lead to the above result.
>
> Given that production compilers are already shipping and making these
> kinds of provenance-based optimisations, if those rules mathematically
> lead to incorrect codegen, then I'd say it's urgent to get clang fixed.
>
> Niall
>



SG14 list run by sg14-owner@lists.isocpp.org

Older Archives on Google Groups