Date: Fri, 15 Jan 2021 15:13:51 -0800 From: Mark Millard <marklmi@yahoo.com> To: Walter von Entferndt <walter.von.entferndt@posteo.net> Cc: freebsd-hackers@freebsd.org Subject: Re: Implicit assumptions (was: Re: Some fun with -O2) Message-ID: <37B00E45-ABCC-4C8D-9BF6-C0DC5142F63A@yahoo.com> In-Reply-To: <5358091.mMMZhaHaU6@t450s.local.lan> References: <mailman.29.1610625600.45116.freebsd-hackers@freebsd.org> <8830694.EFs4ROYVHJ@t450s.local.lan> <4E90FC92-D255-4082-9F89-2BEE4D4C4E92@yahoo.com> <5358091.mMMZhaHaU6@t450s.local.lan>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2021-Jan-15, at 14:25, Walter von Entferndt <walter.von.entferndt at = posteo.net> wrote: > At Freitag, 15. Januar 2021, 21:57:14 CET, Mark Millard wrote: >> The rationale vintage that I have a copy of is available at: >>=20 >> http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf >>=20 > Thank you very much. Now I found that "The result of shifting by a = bit count=20 > greater than or equal to the word's size is undefined behavior in C = and C++"=20 > (https://en.wikipedia.org/wiki/Bitwise_operation#C-family ; likewise = http:// > www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf). The "word size" wording on that wikipedia page is unfortunate and inaccurate. N1570 talks of "negative or is greater than or equal to the width of the promoted left operand". That phrase is not tied to something like 32 on a 32-bit machine. long long is 64 bits wide (or potentially more) and so would allow 0 through 63 based on just this much of the criteria. (But see what follows.) The language standard (various vintages) also tend to talk about "is representable in the result type" vs. not for "<<", as an example. unsigned defines the "not" cases in terms of modulo arithmetic. signed types only define non-negative value left-hand-side cases, and those only when the result "is representable in the result type". signed types otherwise get a "behavior is undefined" classification, or some such wording. The "<<" operation is described via the mathematical multiplication by the power of 2 (the right hand side) as far as what may or may not be "representable". For ">>" and positive values on the left, division by the power of 2 is used. But a negative signed value on the left is described via something like "is implementation defined". For both ">>" and "<<", negative right hand sides result in a "behavior is undefined" classification. > So we'll have to go back=20 > to the loop-solution with the multiply-by-2: > --- check_mktime.c.patch --- > --- check_mktime.c.orig 2021-01-15 03:19:33.962253000 +0100 > +++ check_mktime.c 2021-01-15 23:22:01.951385000 +0100 > @@ -3,6 +3,10 @@ > # include <sys/time.h> > # include <time.h> > # include <unistd.h> > +# include <stdlib.h> > +# include <stdio.h> /* printf() */ > +# include <inttypes.h> /* format spec PRIX64: ll/l + X on 32/64-bit = arch */ > +# include <limits.h> /* CHAR_BIT */ >=20 > /* Work around redefinition to rpl_putenv by other config tests. */ > #undef putenv > @@ -106,9 +110,15 @@ > time_t t, delta; > int i, j; >=20 > - for (time_t_max =3D 1; 0 < time_t_max; time_t_max *=3D 2) > - continue; > - time_t_max--; > + /* portably compute the maximum of a signed type: > + * NOTE: << is undefined if the shift width >=3D word length > + * i.e. shifting a 64-bit type by 62 on a 32-bit machine: undef > + */ > + for (i =3D t =3D 1; i < CHAR_BIT*sizeof t - 1; i++) > + t *=3D 2; > + time_t_max =3D t|(t - 1); > + printf ("time_t_max =3D 0x%"PRIX64"\n", time_t_max); > + > delta =3D time_t_max / 997; /* a suitable prime number */ > for (i =3D 0; i < N_STRINGS; i++) > { =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?37B00E45-ABCC-4C8D-9BF6-C0DC5142F63A>