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