Implicit assumptions (was: Re: Some fun with -O2)

Walter von Entferndt walter.von.entferndt at posteo.net
Sat Jan 16 09:12:50 UTC 2021


At Samstag, 16. Januar 2021, 00:13:51 CET, Mark Millard wrote:
> > Thank you very much.  Now I found that "The result of shifting by a bit
> > count greater than or equal to the word's size is undefined behavior in C
> > and C++" (https://en.wikipedia.org/wiki/Bitwise_operation#C-family ;
> > likewise http:// www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf).
> 
> The "word size" wording on that wikipedia page is
> unfortunate and inaccurate.
> 
> N1570 talks of "negative or is greater than or equal
> to the width of the promoted left operand".
> 
Thx for the clarification.  That means the compute-at-compile-time solution 
would be ok, if there were not...

At Samstag, 16. Januar 2021, 01:26:00 CET, Mark Millard wrote:
[... about pad bits, trap representations, and 1's-complement ...]

Hallelujah.  I did not know that integer representations other than 2's-
complement are allowed in C, and did not take into account these other 
pitfalls.  I've heard of that long ago, but forgot about it.  1's-complement 
is obviously no problem as long we're dealing with non-zero positives.  And I 
did not find anything about the order of any padding bits and the sign bit, 
but I'd strongly assume the sign bit is always adjacent to the value bits?  
At least, no arithmetic operation can alter padding bits (not even a shift)?
https://duckduckgo.com/?q=SEI+CERT+C+Coding provides a simple /popcount()/ 
routine to portably detect padding bits for any integer datatype when given 
it's maximum value.  That could be useful.  If INTMAX_MAX has N padding bits, 
do all other integer types (except *char*) have the same #padding bits?

Can we safely assume this: a *time_t* is either a *long long* iff *long long* 
is supported and it's a 32-bit arch, else *long*?  Or can it be of any of the 
minimum- or least-width integer types?  Or is a *time_t* always of *intmax_t*? 
In the latter case, this gives us a very simple solution:

#include <stdint.h>
static const time_t time_t_max = INTMAX_MAX;

Or do we have to come up with adjacent probing à la:

#include <limits.h>
#include <stdlib.h>
#include <stdio.h>

if (sizeof(intmax_t) == sizeof(time_t))
    time_t_max = INTMAX_MAX;
else
#ifdef __LONG_LONG_SUPPORTED	/* is this macro portable? */
if (sizeof(long long) == sizeof(time_t))
    time_t_max = LLONG_MAX;
else
#endif
if (sizeof(long) == sizeof(time_t))
	time_t_max = LONG_MAX;
else if (sizeof(int) == sizeof(time_t))
	time_t_max = INT_MAX;
else {
	fprintf (stderr, "What the heck is going on?\n");
	exit (EXIT_FAILURE);
}

But reading the standard: time.h declares *clock_t* and *time_t* wich are /
real types/ ... and: "The integer and real floating types are collectively 
called /real types/."  Now I'm out.  Bye.  I tried to be helpful, but this is 
too much...
-- 
=|o)	"Stell' Dir vor es geht und keiner kriegt's hin." (Wolfgang Neuss)




More information about the freebsd-hackers mailing list