On 10/23/12, Kenneth Zadeck <zad...@naturalbridge.com> wrote: > 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.
Well, that's because it's the oversimplified case. :-) >>> 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. And the code could also know that '-n' is a negative number and do the identical conversion. It would certainly be more difficult to write and get all the edge cases. >>> 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. I won't disagree. I was answering what I thought were questions on what was possible. >>> 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. Okay. >>> 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. Unfortunate. -- Lawrence Crowl