On Tue, Aug 7, 2012 at 8:38 PM, Lawrence Crowl <cr...@google.com> wrote:
> On 8/7/12, Richard Guenther <richard.guent...@gmail.com> wrote:
>> On Tue, Aug 7, 2012 at 2:35 AM, Lawrence Crowl <cr...@google.com> wrote:
>> > Convert double_int from a struct with function into a class with
>> > operators and methods.
>> >
>> > This patch adds the methods and operators.  In general functions of
>> > the form "double_int_whatever" become member functions "whatever" or,
>> > when possible, operators.
>> >
>> > Every attempt has been made to preserve the existing algorithms, even
>> > at the expense of some optimization opportunities.  Some examples:
>> >
>> >   The ext operation takes a value and returns a value.  However, that
>> >   return value is usually assigned to the original variable.  An
>> >   operation that modified a variable would be more efficient.
>>
>> That's not always the case though and I think the interface should be
>> consistent with existing behavior to avoid errors creeping in during the
>> transition.
>
> We should probably think about naming conventions for mutating operations,
> as I expect we will want them eventually.

Right.  In the end I would prefer explicit constructors.

>> >   In some cases, an outer sign-specific function calls an inner
>> >   function with the sign as a parameter, which then decides which
>> >   implementation to do.  Decisions should not be artificially
>> >   introduced, and the implementation of each case should be exposed as
>> >   a separate routine.
>> >
>> >   The existing operations are implemented in terms of the new
>> >   operations, which necessarily adds a layer between the new code and
>> >   the existing users.  Once all files have migrated, this layer will
>> >   be removed.
>> >
>> >   There are several existing operations implemented in terms of even
>> >   older legacy operations.  This extra layer has not been removed.
>> >
>> > On occasion though, parameterized functions are often called
>> > with a constant argments.  To support static statement of intent,
>> > and potentially faster code in the future, there are several new
>> > unparameterized member functions.  Some examples:
>> >
>> >   Four routines now encode both 'arithmetic or logical' and 'right or
>> >   left' shift as part of the funciton name.
>> >
>> >   Four routines now encode both 'signed or unsigned' and 'less than or
>> >   greater than' as part of the function name.
>>
>> For most parts overloads that take an (unsigned) HOST_WIDE_INT argument
>> would be nice, as well as the ability to say dbl + 1.
>
> Hm.  There seems to be significant opinion that there should not be any
> implicit conversions.  I am okay with operations as above, but would like
> to hear the opinions of others.

Well, I'd simply add

   double_int operator+(HOST_WIDE_INT);
   double_int operator+(unsigned HOST_WIDE_INT);

and be done with it ;)  Yes, a tad bit more inconvenient on the implementation
side compared to a non-explicit constructor from HOST_WIDE_INT or a
conversion operator ... but adhering to the rule that we do _not_ want such
automatic conversions (well, yet, for the start).

>> > -typedef struct
>> > +typedef struct double_int
>> >  {
>> > +public:
>> > +  /* Normally, we would define constructors to create instances.
>> > +     Two things prevent us from doing so.
>> > +     First, defining a constructor makes the class non-POD in C++03,
>> > +     and we certainly want double_int to be a POD.
>> > +     Second, the GCC conding conventions prefer explicit conversion,
>> > +     and explicit conversion operators are not available until C++11.
>> > */
>> > +
>> > +  static double_int make (unsigned HOST_WIDE_INT cst);
>> > +  static double_int make (HOST_WIDE_INT cst);
>> > +  static double_int make (unsigned int cst);
>> > +  static double_int make (int cst);
>>
>> Did we somehow decide to not allow constructors?  It's odd to convert to
>> C++ and end up with static member functions resembling them ...
>
> Constructors are allowed, but PODs are often passed more efficiently.
> That property seemed particularly important for double_int.

True - I forgot about this issue.  Same for the return values.  I suppose we
need to inspect code quality before going this route.

>> Also I believe the conversion above introduces possible migration errors.
>> Think of a previous
>>
>>  HOST_WIDE_INT a;
>>  double_int d = uhwi_to_double_int (a);
>>
>> if you write that now as
>>
>>  HOST_WIDE_INT a;
>>  double_int d = double_int::make (a);
>>
>> you get the effect of shwi_to_double_int.  Oops.
>
> Hm.  I think the code was more likely to be wrong originally,
> but I take your point.
>
>> So as an intermediate
>> I'd like you _not_ to introduce the make () overloads.
>
> Okay.
>
>> Btw, if HOST_WIDE_INT == int the above won't even compile.
>
> Is that true of any host?  I am not aware of any.  Anyway, it is
> moot if we remove the overloads.

Right.  I'd simply rely on int / unsigned int promotion to HOST_WIDE_INT
or unsigned HOST_WIDE_INT and only provide overloads for HOST_WIDE_INT
kinds anyway.

Richard.

> --
> Lawrence Crowl

Reply via email to