Date: Thu, 14 Jan 2021 11:00:31 -0800 From: Mark Millard <marklmi@yahoo.com> To: Walter von Entferndt <walter.von.entferndt@posteo.net> Cc: freebsd-hackers@freebsd.org Subject: Re: Implicit assuptions (was: Re: Some fun with -O2) Message-ID: <AE6F148E-3733-4CAE-A4D7-A2E940688E40@yahoo.com> In-Reply-To: <12075361.5MqMfjp4zD@t450s.local.lan> References: <mailman.29.1610625600.45116.freebsd-hackers@freebsd.org> <12075361.5MqMfjp4zD@t450s.local.lan>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2021-Jan-14, at 09:44, Walter von Entferndt = <walter.von.entferndt@posteo.net> wrote: > At Donnerstag, 14. Januar 2021, 13:00:00 CET, Konstantin Belousov = wrote: >> The time_t type is signed, then the loop >> for (time_t_max =3D 1; 0 < time_t_max; time_t_max *=3D 2) >> continue; >>=20 >> intent is to get signed overflow, which is UB. Modern compilers = prefer to >> shoot into your foot instead of following common sense. >>=20 > The next line in the program is: time_t_max--; >=20 > The problem here is one of the most common in programming: to rely on = an / > implicit assumption/ (e.g. how the compiler (or the CPU,...) handles = some=20 > expression). Obviously, the above loop condition (0 < time_t_max) is=20= > (mathematically) always true and thus can be optimized right away to = an=20 > infinite loop. Isn't that common sense, too? How should the compiler = (or the=20 > CPU) know that this was /not/ intended? >=20 >> Workaround is to add -fwrapv compiler switch. >>=20 > And the correct solution is: Do not rely on implicit assumptions. = Instead,=20 > write down /explicitely/ what you intend to do or get as result. If = that's=20 > not possible (or too complicated), at least add a comment explaining = your=20 > intention. >=20 > Since the behaviour on signed overflow is undefined in C, the above = statement=20 > must be rewritten completely. For the case above, it's obvious (also = from the=20 > name of the variable) that the author wants to have time_t_max =3D = the largest=20 > possible positive number of type time_t (all bits 1 except the sign = bit). OK,=20 > then write that instead: >=20 > [add #include <stdlib.h>] > add #include <limits.h> > change static time_t time_t_max; > to static const time_t time_t_max =3D LONG_MAX; > [because time_t equals long int] Not on FreeBSD for 32-bit powerpc it is not: time_t is 64 bits wide there but long int is not: =46rom /usr/include/machine/_types.h : typedef __int64_t __time_t; /* time()... */ =46rom /usr/include/sys/types.h : typedef __time_t time_t; > del for (time_t_max =3D 1; 0 < time_t_max; time_t_max *=3D 2) > del continue; > del time_t_max--; >=20 > You may also > add #include <stdio.h> > add printf ("time_t_max =3D %ld\n", time_t_max); >=20 > in main() to verify that's giving you what you want. =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?AE6F148E-3733-4CAE-A4D7-A2E940688E40>