[tz] [PROPOSED 1/7] Avoid undefined behavior if no Link lines
Clive D.W. Feather
clive at davros.org
Thu Oct 27 06:38:42 UTC 2022
Paul Eggert said:
> I use these debugging options partly to check tzcode's portability.
> Although qsort(NULL, 0, ...) works fine on most practical platforms, as
> Clive noted there is (or was) an oddball platform or two that is (or
> was) verrrry picky about pointers, and for a program like zic where
> portability is more important than performance, it's nice if zic runs
> even on oddballs. Clive, do you happen to know what these platforms are
> (or were), and whether they're still supported?
Sorry, but I have no idea. We didn't always get told - if someone at the
meeting said "I know an platform that does X", we believed them.
There was a longstanding meme in the meetings (and on comp.std.c) that "if
you don't understand the reasoning behing something in the C Standard, the
answer is the IBM AS400".
> As a practical matter, even though the C standard says that expressions
> like qsort(NULL, 0, ...) and (char *)NULL + 0 have undefined behavior,
> any new platform would be verrrry wise to define them to work the same
> way that most practical platforms do; this is true regardless of what
> the C standard says. And to some extent this means the C standard is not
> at the sweetest spot it could be in, as a contract between implementers
> and programmers. I write and see a lot of code where adding 0 to NULL is
> expected to yield NULL, and nobody thinks twice about it (nor should they).
Why not? You're assuming that NULL is represented by 32 or 64 zero bits [1].
That's not what all computers do. Unusual architectures may do something
completely different and they might well trap on trying to add to a null
pointer, irrespective of the value you're adding.
This is, indeed, a modern version of the "all the world's a Vax" fallacy.
[1] For those not used to this particular discussion, an integer *constant*
that evaluates to zero, or one of those cast to a pointer type, is how you
represent a null pointer. But that does not mean that:
#define UCPSIZE (sizeof (unsigned char *))
union
{
unsigned char *p;
char c [UCPSIZE];
}
u;
u.p = NULL;
unsigned char z = 0;
for (unsigned int i = 0; i < UCPSIZE; i++)
z |= u.c [i];
printf ("Result = %u\n", z);
is required to print zero. On the contrary, the representation of a null
pointer is completely unspecified.
--
Clive D.W. Feather | If you lie to the compiler,
Email: clive at davros.org | it will get its revenge.
Web: http://www.davros.org | - Henry Spencer
Mobile: +44 7973 377646
More information about the tz
mailing list