Date: Sat, 16 Jan 2021 14:08:30 -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: <ABC6559D-66E6-4671-A11A-FA225B55C9B6@yahoo.com> In-Reply-To: <1648904.MsCH1bHPGx@t450s.local.lan> References: <mailman.29.1610625600.45116.freebsd-hackers@freebsd.org> <1725854.nNRVL2rNYg@t450s.local.lan> <7623BADF-5FA9-4712-8D85-A1D2B82E3F74@yahoo.com> <1648904.MsCH1bHPGx@t450s.local.lan>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2021-Jan-16, at 12:19, Walter von Entferndt <walter.von.entferndt at = posteo.net> wrote: > At Samstag, 16. Januar 2021, 11:23:03 CET, Mark Millard wrote: >> This is the sort of thing where FreeBSD and Linux use a C subset >> for the specific issue, as defined by POSIX.1-2017/"The Open Group >> Base Specifications" Issue 7, 2018 edition/IEEE STd 1003-2017/... . >> For example: >>=20 >> = https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html= >>=20 >> reports (in its own terminology that may not be a full match to C's): >>=20 >> QUOTE >> clock_t shall be an integer or real-floating type. time_t shall be an >> integer type. END QUOTE >>=20 >> Limiting to such a time_t is easier to cover. [...] >> Restricting time_t to integer types leaves a compatible context. >> So: no "conflict" in that respect. >>=20 > My understanding is that check_mktime.c is a test program called by = autoconf=20 > or such, designed to run on various UNIX platforms? I mean it does = not only=20 > need to run on BSD & Linux. QUOTE ( from https://en.wikipedia.org/wiki/POSIX ) The Portable Operating System Interface (POSIX) is a family of standards = specified by the IEEE Computer Society for maintaining compatibility = between operating systems.[1] POSIX defines the application programming = interface (API), along with command line shells and utility interfaces, = for software compatibility with variants of Unix and other operating = systems. END QUOTE The section "POSIX-oriented operating systems" lists many OSs that are either certified, mostly-compliant, have means of having a POSIX environment (includes Microsoft Windows, OS/2, DOS), or have a (optional) POSIX compatibility layer. I'll not make a full list here. You can use that to help judge if only supporting time_t as an integer type is worthwhile in your view. > Maybe something like this will cover the most cases in practice: There are more details here that I'd need to think about that I've not dealt with yet. > --- check_mktime.c.patch --- > --- check_mktime.c.orig 2021-01-15 03:19:33.962253000 +0100 > +++ check_mktime.c 2021-01-16 21:00:36.160616000 +0100 > @@ -3,6 +3,13 @@ > # include <sys/time.h> > # include <time.h> > # include <unistd.h> > +# include <stdlib.h> > +#include <stdint.h> > +# include <stdio.h> /* printf() */ > +# include <limits.h> /* CHAR_BIT */ > +#if 0 > +# include <inttypes.h> /* format spec PRIX64: ll/l + X on = 32/64-bit arch */ > +#endif >=20 > /* Work around redefinition to rpl_putenv by other config tests. */ > #undef putenv > @@ -16,6 +23,78 @@ > }; > #define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0])) >=20 > +/* Count the bits set in any unsigned integer type. > + * Returns the precision (width - padding bits - sign bit) iff given > + * the xxx_MAX value of any integer type, signed or unsigned. > + * =46rom SEI CERT C Coding Standard: > + * Rules for Developing Safe, Reliable, and Secure Systems (2016) > + */ > +size_t > +popcount (num) > +uintmax_t num; > +{ > + size_t cnt =3D 0; > + =20 > + while (num !=3D 0) > + { > + if (num % 2 =3D=3D 1) > + cnt++; > + num >>=3D 1; > + } > + return cnt; > +} > +#define PRECISION(max_value) popcount(max_value) > + > +/* Guess the maximum value of a time_t from it's storage width. > + * ASSERT time_t is not a floating point, or of any arcane width, or=20= > unsigned. > + * Only 4...8 byte width of a time_t are tested. > + * On error: returns (time_t)(-1) > + */ > +time_t > +guess_time_t_max () > +{ > + time_t t0, t1 =3D (time_t)(-1); > + size_t size, prec; > + > + switch ((size =3D sizeof(time_t))) > + { > + case 4: > + prec =3D PRECISION((time_t) 0xFFFFFFFF); > + break; > + case 5: > + prec =3D PRECISION((time_t) 0xFFFFFFFFFF); > + break; > + case 6: > + prec =3D PRECISION((time_t) 0xFFFFFFFFFFFF); > + break; > + case 7: > + prec =3D PRECISION((time_t) 0xFFFFFFFFFFFFFF); > + break; > + case 8: > + prec =3D PRECISION((time_t) 0xFFFFFFFFFFFFFFFF); > + break; > + default: > + prec =3D 1; > + break; > + } > + prec--; /* assumption: time_t is signed */ > + if (prec) > + { > + t0 =3D (time_t) 1 << (prec - 1); > + t1 =3D t0|(t0 - 1); > + } > + > + /* FIXME not portable: time_t can be floating point type, > + * or another integer type other than long or long long. > + * > + fprintf (stderr, "time_t_max\t=3D 0x%"PRIX64"\n", t1);*/ > + fprintf (stderr, "sizeof(time_t)\t=3D %2zd byte\n", size); > + fprintf (stderr, "precision\t=3D %2zd bit\n", prec); > + fprintf (stderr, "padding\t\t=3D %2zd bit\n", size*CHAR_BIT - prec = - 1 /*=20 > sign */); > + > + return t1; > +} > + > /* Fail if mktime fails to convert a date in the spring-forward gap. > Based on a problem report from Andreas Jaeger. */ > static void > @@ -106,9 +185,7 @@ > 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--; > + time_t_max =3D guess_time_t_max (); > delta =3D time_t_max / 997; /* a suitable prime number */ > for (i =3D 0; i < N_STRINGS; i++) > { > @@ -128,3 +205,4 @@ > spring_forward_gap (); > exit (0); > } > +/*! vi: set ai tabstop=3D8 shiftwidth=3D2: */ >=20 =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?ABC6559D-66E6-4671-A11A-FA225B55C9B6>