Implicit assuptions (was: Re: Some fun with -O2)
Mark Millard
marklmi at yahoo.com
Thu Jan 14 19:00:36 UTC 2021
On 2021-Jan-14, at 09:44, Walter von Entferndt <walter.von.entferndt at 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 = 1; 0 < time_t_max; time_t_max *= 2)
>> continue;
>>
>> intent is to get signed overflow, which is UB. Modern compilers prefer to
>> shoot into your foot instead of following common sense.
>>
> The next line in the program is: time_t_max--;
>
> 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
> expression). Obviously, the above loop condition (0 < time_t_max) is
> (mathematically) always true and thus can be optimized right away to an
> infinite loop. Isn't that common sense, too? How should the compiler (or the
> CPU) know that this was /not/ intended?
>
>> Workaround is to add -fwrapv compiler switch.
>>
> And the correct solution is: Do not rely on implicit assumptions. Instead,
> write down /explicitely/ what you intend to do or get as result. If that's
> not possible (or too complicated), at least add a comment explaining your
> intention.
>
> Since the behaviour on signed overflow is undefined in C, the above statement
> must be rewritten completely. For the case above, it's obvious (also from the
> name of the variable) that the author wants to have time_t_max = the largest
> possible positive number of type time_t (all bits 1 except the sign bit). OK,
> then write that instead:
>
> [add #include <stdlib.h>]
> add #include <limits.h>
> change static time_t time_t_max;
> to static const time_t time_t_max = 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:
From /usr/include/machine/_types.h :
typedef __int64_t __time_t; /* time()... */
From /usr/include/sys/types.h :
typedef __time_t time_t;
> del for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2)
> del continue;
> del time_t_max--;
>
> You may also
> add #include <stdio.h>
> add printf ("time_t_max = %ld\n", time_t_max);
>
> in main() to verify that's giving you what you want.
===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)
More information about the freebsd-hackers
mailing list