On Tue, Oct 24, 2017 at 3:24 PM, Richard Sandiford <richard.sandif...@linaro.org> wrote: > Richard Biener <richard.guent...@gmail.com> writes: >> On Tue, Oct 24, 2017 at 2:48 PM, Richard Sandiford >> <richard.sandif...@linaro.org> wrote: >>> Richard Biener <richard.guent...@gmail.com> writes: >>>> On Tue, Oct 24, 2017 at 1:23 PM, Richard Sandiford >>>> <richard.sandif...@linaro.org> wrote: >>>>> Eric Botcazou <ebotca...@adacore.com> writes: >>>>>>> Yeah. E.g. for ==, the two options would be: >>>>>>> >>>>>>> a) must_eq (a, b) -> a == b >>>>>>> must_ne (a, b) -> a != b >>>>>>> >>>>>>> which has the weird property that (a == b) != (!(a != b)) >>>>>>> >>>>>>> b) must_eq (a, b) -> a == b >>>>>>> may_ne (a, b) -> a != b >>>>>>> >>>>>>> which has the weird property that a can be equal to b when a != b >>>>>> >>>>>> Yes, a) was the one I had in mind, i.e. the traditional operators are >>>>>> the must >>>>>> variants and you use an outer ! in order to express the may. Of >>>>>> course this >>>>>> would require a bit of discipline but, on the other hand, if most of >>>>>> the cases >>>>>> fall in the must category, that could be less ugly. >>>>> >>>>> I just think that discipline is going to be hard to maintain in practice, >>>>> since it's so natural to assume (a == b || a != b) == true. With the >>>>> may/must approach, static type checking forces the issue. >>>>> >>>>>>> Sorry about that. It's the best I could come up with without losing >>>>>>> the may/must distinction. >>>>>> >>>>>> Which variant is known_zero though? Must or may? >>>>> >>>>> must. maybe_nonzero is the may version. >>>> >>>> Can you rename known_zero to must_be_zero then? >>> >>> That'd be OK with me. >>> >>> Another alternative I wondered about was must_eq_0 / may_ne_0. >>> >>>> What's wrong with must_eq (X, 0) / may_eq (X, 0) btw? >>> >>> must_eq (X, 0) generated a warning if X is unsigned, so sometimes you'd >>> need must_eq (X, 0) and sometimes must_eq (X, 0U). >> >> Is that because they are templates? Maybe providing a partial specialization >> would help? > > I don't think it's templates specifically. We end up with something like: > > int f (unsigned int x, const int y) > { > return x != y; > } > > int g (unsigned int x) { return f (x, 0); } > > which generates a warning too. > >> I'd be fine with must_eq_p and may_eq_0. > > OK, I'll switch to that if there are no objections.
Hum. But then we still warn for must_eq_p (x, 1), no? So why does int f (unsigned int x) { return x != 0; } not warn? Probably because of promotion of the arg. Shouldn't we then simply never have a may/must_*_p (T1, T2) with T1 and T2 being not compatible? That is, force promotion rules on them with template magic? Richard. > Thanks, > Richard