tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: netbsd-11 gcc bug



On Sun, May 24, 2026 at 08:33:19AM -0400, Mouse wrote:
 > > It is not about gcc or clang, it is about the C standard, which is
 > > created by an open comittee and you are welcome to send defect
 > > reports and/or ask for clarifictaions.
 > 
 > Which is fair - but compilers do not have to take advantage of all the
 > leeway the standard gives them.  "Undefined behaviour" can, after all,
 > include "exactly what the code author intended".
 >
 > [...]

No, formally it can't, because "undefined" means "meaningless".

The root of these problems is that long ago a bunch of the undefined
and unspecified behavior in C was understood as being that way to
leave room for exotic hardware, and there was a corresponding
expectation that the compiler would do the obvious thing and the
exotic or not-so-exotic behavior of your actual hardware would
determine the behavior.

Correspondingly, people would write code assuming they were never
going to run it on a 286, or a one's complement machine, in the
presence of Multics segments, or whatever, and it worked, and nobody
worried about it.

This understanding had already disappeared entirely upstream more than
twenty years ago now, and it's a lost cause. You can't write machine-
dependent C that way any more; every available compiler will mangle
it.

There are many reasons for this. One is that most of the exotic
hardware that room was left for is dead and forgotten. Why are there
holes in the standard related to signed shifts and signed integer
overflow? There's no reason whatsoever now. It's been a long time
since anyone bothered with hardware that didn't have a signed right
shift instruction, and longer still since anyone had real hardware
whose signed integers weren't two's complement. Normal people don't
consider DS9000s irrelevant, they've never even got as far as having
heard of the idea.

Another is that the existence of C++ has prevented fixing anything in
C; thus it hasn't kept up with compiler technology. The places where
certain bits of undefined and unspecified behavior line up exactly
with things that mattered in a compiler written forty years ago are no
longer obvious, and so what's left is a vague general belief that the
UB in the C standard is meant to be room for optimizers.

A third is that few people in the programming languages and compilers
world, especially the academic parts of it, have any appreciation for
(or real understanding of) C and think of it as a design bug with no
redeeming features. This (at best) makes exploiting undefined behavior
into a game, like writing demos for old weird hardware. Not only is
there no understanding of what the affordances might have been
intended for, there's not even any awareness that this is even a point
to consider.

You can try pushing back, but you aren't going to get anywhere.

 > If &p->member is undefined behaviour when p is nil,
 > the correct thing for a *useful* compiler to do is not to simply assume
 > p is non-nil, at least not unless specifically told to; it is to test
 > for nil and take some suitable action - indirect through it, call a
 > (possibly invocation-dependent) routine, *something* better than
 > silently propagating the inference.  Especially in the presence of an
 > explicit test for nil later!

...no. Inserting extra code is never going to fly, all that'll ever
result from that is people thinking your compiler is broken. The
correct thing here is to warn that the null test downstream is
redundant at the same time as removing it. There are a few cases where
it's hard to generate meaningful warnings from UB inference, and
therefore at least sort of excusable not to, but this isn't one of
them.

A smarter compiler or program checker might instead note the explicit
null checks elsewhere, conclude that it's intended to be possible for
the pointer to be null, and warn about the missing null test at the
point that does &p->x. That requires marginally more work than just
tracking whether a pointer can be null (instead you need to track
whether we know it can't be null, whether we know it can, or if we
aren't sure) but isn't exactly difficult.

-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index