This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On 10/23/12, Kenneth Zadeck <zadeck@naturalbridge.com> wrote:I am not a c++ hacker. if someone wants to go there later, we can investigate this.On 10/23/2012 02:38 PM, Lawrence Crowl wrote:Well, that's because it's the oversimplified case. :-)On 10/23/12, Kenneth Zadeck <zadeck@naturalbridge.com> wrote:On 10/23/2012 10:12 AM, Richard Biener wrote:Starting from the simple case, you write an operator ==.+ 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.
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.
What would you have done with w.minus_one_p ()?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?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.
There is certainly a desire here not to let the ugliness of the back end not drag down the tree level. But the truth is that with respect to the signedness, the tree level is very dirty. If the double int code had taken a type from the start, things may have been different. But the truth is that sign is different than size, some of the operations do not care about sign and some of the transformations that we want to do we do need them to be done in a particular but that is not dependent on the sign of the type. Richi has beat me up about this but i actually believe that most of the time when the sign of the type does not match the sign of the operation, the code is actually correct.
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.
Okay.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.
Unfortunate.i have, and it does not work.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.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |