On 10/23/2012 02:38 PM, Lawrence Crowl wrote:
On 10/23/12, Kenneth Zadeck <zad...@naturalbridge.com> wrote:
On 10/23/2012 10:12 AM, Richard Biener wrote:
+  inline bool minus_one_p () const;
+  inline bool zero_p () const;
+  inline bool one_p () const;
+  inline bool neg_p () const;

what's wrong with w == -1, w == 0, w == 1, etc.?
I would love to do this and you seem to be somewhat knowledgeable
of c++.  But i cannot for the life of me figure out how to do it.
Starting from the simple case, you write an operator ==.

as global operator:  bool operator == (wide_int w, int i);
as member operator:  bool wide_int::operator == (int i);

In the simple case,

bool operator == (wide_int w, int i)
{
   switch (i)
     {
       case -1: return w.minus_one_p ();
       case  0: return w.zero_p ();
       case  1: return w.one_p ();
       default: unexpected....
     }
}

no, this seems wrong. you do not want to write code that can only fail at runtime unless there is a damn good reason to do that.
say i have a TImode number, which must be represented in 4 ints
on a 32 bit host (the same issue happens on 64 bit hosts, but
the examples are simpler on 32 bit hosts) and i compare it to -1.
The value that i am going to see as the argument of the function
is going have the value 0xffffffff.  but the value that i have
internally is 128 bits.  do i take this and 0 or sign extend it?
What would you have done with w.minus_one_p ()?
the code "knows" that -1 is a negative number and it knows the precision of w. That is enough information. So it logically builds a -1 that has enough bits to do the conversion.


in particular if someone wants to compare a number to 0xdeadbeef i
have no idea what to do.  I tried defining two different functions,
one that took a signed and one that took and unsigned number but
then i wanted a cast in front of all the positive numbers.
This is where it does get tricky.  For signed arguments, you should sign
extend.  For unsigned arguments, you should not.  At present, we need
multiple overloads to avoid type ambiguities.

bool operator == (wide_int w, long long int i);
bool operator == (wide_int w, unsigned long long int i);
inline bool operator == (wide_int w, long int i)
   { return w == (long long int) i; }
inline bool operator (wide_int w, unsigned long int i)
   { return w == (unsigned long long int) i; }
inline bool operator == (wide_int w, int i)
   { return w == (long long int) i; }
inline bool operator (wide_int w, unsigned int i)
   { return w == (unsigned long long int) i; }

(There is a proposal before the C++ committee to fix this problem.)

Even so, there is room for potential bugs when wide_int does not
carry around whether or not it is signed.  The problem is that
regardless of what the programmer thinks of the sign of the wide int,
the comparison will use the sign of the int.
when they do we can revisit this. but i looked at this and i said the potential bugs were not worth the effort.

If there is a way to do this, then i will do it, but it is going
to have to work properly for things larger than a HOST_WIDE_INT.
The long-term solution, IMHO, is to either carry the sign information
around in either the type or the class data.  (I prefer type, but
with a mechanism to carry it as data when needed.)  Such comparisons
would then require consistency in signedness between the wide int
and the plain int.
carrying the sign information is a non starter. The rtl level does not have it and the middle end violates it more often than not. My view was to design this having looked at all of the usage. I have basically converted the whole compiler before i released the abi. I am still getting out the errors and breaking it up in reviewable sized patches, but i knew very very well who my clients were before i wrote the abi.

I know that double-int does some of this and it does not carry
around a notion of signedness either.  is this just code that has
not been fully tested or is there a trick in c++ that i am missing?
The double int class only provides == and !=, and only with other
double ints.  Otherwise, it has the same value query functions that
you do above.  In the case of double int, the goal was to simplify
use of the existing semantics.  If you are changing the semantics,
consider incorporating sign explicitly.

i have, and it does not work.

Reply via email to