Skip site navigation (1)Skip section navigation (2)
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>