Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Jan 2021 23:08:08 +0100
From:      Walter von Entferndt <walter.von.entferndt@posteo.net>
To:        freebsd-hackers@freebsd.org
Subject:   Implicit assumptions (was: Re: Some fun with -O2)
Message-ID:  <4569591.1rqTVSEV2j@t450s.local.lan>
In-Reply-To: <AE6F148E-3733-4CAE-A4D7-A2E940688E40@yahoo.com>
References:  <mailman.29.1610625600.45116.freebsd-hackers@freebsd.org> <12075361.5MqMfjp4zD@t450s.local.lan> <AE6F148E-3733-4CAE-A4D7-A2E940688E40@yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
At Donnerstag, 14. Januar 2021, 20:00:31 CET, Mark Millard wrote:
> 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;
> 
Ha! Thx... Ok, then we have to use the *sizeof* operator and if you thought 
there's one holy constant in computer science - that a byte has 8 bits, and we 
can use that as an ... /implicit assumption/ ... - you might be surprised that 
it's declared explicitely in
sys/param.h:#define     NBBY    8               /* number of bits in a byte */
and you can find the number 8 (and 16, 24, 32, 48,...) all over other header 
files without using that definition (NBBY) so these are strictly speaking all 
wrong... ;)  So now we have (errorneous!)

[delete #include <limits.h>]
#include <sys/param.h>

time_t time_t_max;
...
for (i = time_t_max = 1; i < NBBY*sizeof time_t_max; i++)
	time_t_max *= 2;
time_t_max--;

which gives the intended result but is strictly speaking wrong, because it you 
don't do the decrement, the value is negative, and the decrement of a negative 
number should be negative, too.  I.e. this only gives what we want because we 
make use of an undefined behaviour.  So let's do better (and portable):

#include <sys/param.h>
signed_t signed_max, t1;

for (int i = signed_max = 1; i < NBBY*sizeof signed_max - 1; i++) {
          signed_max *= 2;	// eq: signed_max <<= 1;
          t1 = signed_max - 1;
  }
  signed_max += t1;		// eq: signed_max |= t1;
/* QED
 * hopefully the compiler optimizes *=2 and we're using binary numbers ;)
 */
--
=|o)	"Stell' Dir vor es geht und keiner kriegt's hin." (Wolfgang Neuss)





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4569591.1rqTVSEV2j>