Re: About issue 0001108 and abs(INT_MIN)

2018-07-23 Thread Vincent Lefevre
On 2018-07-23 20:24:11 +0700, Robert Elz wrote:
> Date:Mon, 23 Jul 2018 15:13:21 +0200
> From:Vincent Lefevre 
> Message-ID:  <20180723131321.gb12...@zira.vinc17.org>
> 
>   | No, this is not impossible. The result of the test is 0.
> 
> Yes, I know, what I meant was that it is impossible for an
> unsigned value to ever be < 0 - which is what that test is
> based upon.

No, this is just a test. The expression is a valid C expression
with a well-defined result, which may be 0 or 1.

> But because of that, if one writes code like
> 
>   unsigned x,y,z;
> 
>   z = x - y;
>   if (z < 0) { /* whatever */ }
> 
> the code is broken,

This is valid C code. The "if (z < 0) { /* whatever */ }" is just
dead code here. But this is not incorrect. Whether this is what
the user intended to write is another matter.

> and because of that, compilers warn about it

GCC will warn just with -Wtype-limits, which isn't even in -Wall,
thus not in general because such always-true or always-false tests
are common with portability code:

  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12963

But even if one gets a warning, this doesn't make the code wrong.
Warnings are there just to signal a potential issue, sometimes
with many false positives, like with this kind of tests.

And my code was different: (T) -1 < 0

Here, (T) -1 is a constant expression. Thus GCC shouldn't warn on it,
even with -Wtype-limits, as documented:

  -Wtype-limits
 Warn if a comparison is always true or always false due to the
 limited range of the data type, but do not warn for constant
 
 expressions.  For example, warn if an unsigned variable is compared
 ^^^
 against zero with "<" or ">=".  This warning is also enabled by
 -Wextra.

I get a warning, but this is a bug in the compiler. The goal concerning
constant expressions is to avoid even more false positives.

> (just like, in this meaningless example, they would also warn about
> x and y being used without being set...)

This other warning is useful because this is undefined behavior.

-- 
Vincent Lefèvre  - Web: 
100% accessible validated (X)HTML - Blog: 
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)



Re: About issue 0001108 and abs(INT_MIN)

2018-07-23 Thread Vincent Lefevre
On 2018-07-23 20:04:21 +0700, Robert Elz wrote:
> Date:Mon, 23 Jul 2018 14:48:36 +0200
> From:Vincent Lefevre 
> Message-ID:  <20180723124836.ga12...@zira.vinc17.org>
> 
>   | For the signness, one can just do: (T) -1 < 0
> 
> Until the brain dead compilers started bitching about comparing
> an unsigned number for < 0 (which is impossible, of course, that's
> the point)

No, this is not impossible. The result of the test is 0.

> and by so doing breaking things - at least in envoronments which
> insist on switching on all warnings, and also treating all warnings
> as compile errors.

If compilers don't handle the above test, they are really broken.
(T) -1 < 0 is well defined in C, whether T is signed or unsigned.

-- 
Vincent Lefèvre  - Web: 
100% accessible validated (X)HTML - Blog: 
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)



Re: About issue 0001108 and abs(INT_MIN)

2018-07-23 Thread Robert Elz
Date:Mon, 23 Jul 2018 14:48:36 +0200
From:Vincent Lefevre 
Message-ID:  <20180723124836.ga12...@zira.vinc17.org>

  | For the signness, one can just do: (T) -1 < 0

Until the brain dead compilers started bitching about comparing
an unsigned number for < 0 (which is impossible, of course, that's
the point) and by so doing breaking things - at least in envoronments
which insist on switching on all warnings, and also treating all warnings
as compile errors.

kre




Re: About issue 0001108 and abs(INT_MIN)

2018-07-23 Thread Joerg Schilling
Vincent Lefevre  wrote:

> On 2018-07-23 08:06:46 +, Schwarz, Konrad wrote:
> > I don't think such code (to detect whether an arbitrary type is
> > signed or unsigned) exists.
>
> For the signness, one can just do: (T) -1 < 0
>
> Then, to get the minimum value of a signed type, assuming
> two's complement and no padding bits:
>
>   (2 * -((T) 1 << (sizeof(T) * CHAR_BIT - 2)))
>
> as said in the message I've posted a few days ago.

You can even check the hardware type.

On thursday, I changed my code to:

#define TYPE_ISSIGNED(t)(((t)-1) < ((t)0)) 
#define TYPE_ISUNSIGNED(t)  (!TYPE_ISSIGNED(t)) 
#if (-3 & 3) == 1   /* Two's complement */ 
#define TYPE_MSBVAL(t)  (2 * -(((t)1) << (sizeof (t)*CHAR_BIT - 2))) 
#else 
#define TYPE_MSBVAL(t)  ((t)(~((t)0) << (sizeof (t)*CHAR_BIT - 1))) 
#endif 
#define TYPE_MINVAL(t)  (TYPE_ISSIGNED(t)   \ 
? TYPE_MSBVAL(t)\ 
: ((t)0)) 
#define TYPE_MAXVAL(t)  ((t)(~((t)0) - TYPE_MINVAL(t))) 


As a hint, you may use:

#if (-3 & 3) == 1
two's complement
#elif (-3 & 3) == 0
one's complement
#elif (-3 & 3) == 3
magnitude type
#endif

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/'



Re: About issue 0001108 and abs(INT_MIN)

2018-07-23 Thread Vincent Lefevre
On 2018-07-23 08:06:46 +, Schwarz, Konrad wrote:
> I don't think such code (to detect whether an arbitrary type is
> signed or unsigned) exists.

For the signness, one can just do: (T) -1 < 0

Then, to get the minimum value of a signed type, assuming
two's complement and no padding bits:

  (2 * -((T) 1 << (sizeof(T) * CHAR_BIT - 2)))

as said in the message I've posted a few days ago.

-- 
Vincent Lefèvre  - Web: 
100% accessible validated (X)HTML - Blog: 
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)



RE: About issue 0001108 and abs(INT_MIN)

2018-07-23 Thread Schwarz, Konrad



> -Original Message-
> From: Joerg Schilling [mailto:joerg.schill...@fokus.fraunhofer.de]
> Sent: Thursday, July 19, 2018 4:53 PM
> To: vincent-o...@vinc17.net; austin-group-l@opengroup.org
> Subject: Re: About issue 0001108 and abs(INT_MIN)
> 
> Vincent Lefevre  wrote:
> 
> > The problem is not just the warning. If t is signed,
> >
> >   ((t)(~((t)0) << (sizeof (t)*CHAR_BIT - 1)))
> >
> > will yield undefined behavior due to overflow. This means that
> > compilers may generate code that shows a behavior different from what

> A compiler that creates other than the expected behavior would need to create
> intentionally buggy code.
> 
> The question was to create working code that neither creates a warning with 
> newer
> nor with older compilers. Do you have such code?

I don't think such code (to detect whether an arbitrary type is signed or 
unsigned) exists.

As Vincent correctly wrote, signed arithmetic is allowed to trap;
my understanding is that this was so C could support IBM360-derived 
architectures
(non-trapping signed arithmetic is a recent addition to z-Series).

POSIX acknowledges the inability to programmatically discover the by stating, 
for each typedef
it specifies (e.g. in sys/types.h), whether the type is signed or unsigned.  
Where it does not, e.g., time_t
computation is significantly complicated, e.g., difftime() must be used in 
portable code.

((t) 1 << sizeof (t) * CHAR_BIT - 1) is an expression that evaluates to a 
t-sized word with the most
significant bit set.

Regards

Konrad