Davin McCall <dav...@davmac.org> wrote:

> On 19/07/18 13:03, Joseph Myers wrote:
>
> On Thu, 19 Jul 2018, Joerg Schilling wrote:
>
>
>
> [...]
>
> Since POSIX de-facto only allowed two's complement machines since several 
> years
> already (the current change is just fixing the slipped parts in the standard),
> it is now well defined what happens in case of an integer overflow.
>
>
>
> No, it is very definitely undefined.  It's true that anyone programming in
> C on POSIX systems for about the past 20 years has probably in fact only
> needed to care about two's complement systems.  But it's also true that
> programming in C for about the past 20 years without a proper modern
> understanding of undefined behavior as discussed in the above blog posts
> (or otherwise avoiding anything the C standard says is undefined) is a
> rapid route to code that does not work correctly and introduces security
> holes.

If you believe this all makes sense, you are welcome to present new code for 
this piece of code:

#ifndef CHAR_BIT 
#ifdef  NBBY 
#define CHAR_BIT        NBBY 
#endif 
#endif 
 
/* 
 * Last resort: define CHAR_BIT by hand 
 */ 
#ifndef CHAR_BIT 
#define CHAR_BIT        8 
#endif 
 
/* 
 * These macros may not work on all platforms but as we depend 
 * on two's complement in many places, they do not reduce portability. 
 * The macros below work with 2s complement and ones complement machines. 
 * Verify with this table... 
 * 
 *      Bits    1's c.  2's complement. 
 *      100     -3      -4 
 *      101     -2      -3 
 *      110     -1      -2 
 *      111     -0      -1 
 *      000     +0       0 
 *      001     +1      +1 
 *      010     +2      +2 
 *      011     +3      +3 
 * 
 * Computing -TYPE_MINVAL(type) will not work on 2's complement machines 
 * if 'type' is int or more. Use: 
 *              ((unsigned type)(-1 * (TYPE_MINVAL(type)+1))) + 1; 
 * it works for both 1's complement and 2's complement machines. 
 */ 
#define TYPE_ISSIGNED(t)        (((t)-1) < ((t)0)) 
#define TYPE_ISUNSIGNED(t)      (!TYPE_ISSIGNED(t)) 
#define TYPE_MSBVAL(t)          ((t)(~((t)0) << (sizeof (t)*CHAR_BIT - 1))) 
#define TYPE_MINVAL(t)          (TYPE_ISSIGNED(t)                       \ 
                                    ? TYPE_MSBVAL(t)                    \ 
                                    : ((t)0)) 
#define TYPE_MAXVAL(t)          ((t)(~((t)0) - TYPE_MINVAL(t))) 


It worked for 20 years without problems but recently some compilers decided to 
issue a warning.

Note that the code you present 

-       needs to work on any platform used by UNIX

-       needs to work with any type from char up to the largest kardinal type 
        supported by the actual compiler

-       needs to work with compilers that do not support "long long".

Jörg

-- 
 EMail:jo...@schily.net                    (home) Jörg Schilling D-13353 Berlin
    joerg.schill...@fokus.fraunhofer.de (work) Blog: http://schily.blogspot.com/
 URL: http://cdrecord.org/private/ http://sf.net/projects/schilytools/files/'

Reply via email to