On 30/05/12 17:33, Michel Fortin wrote:
On 2012-05-30 14:44:37 +0000, "Steven Schveighoffer"
<schvei...@yahoo.com> said:

On Tue, 29 May 2012 13:35:12 -0400, Michel Fortin
<michel.for...@michelf.com> wrote:

Personally, I think it'd be much cleaner to go with some kind of
magic function than trying to match the condition against a
predefined pattern. Something like da.isSliceOf(a), which could do
the usual pointer thing at runtime and call some sort of CTFE
intrinsic at compile-time.

That doesn't help when most code does not use this today. I.e. one of
the main benefits of ctfe is that you don't *have* to write special code.

But at the other end, there should be an easy to understand separation
between what is supported by CTFE and what is not. Once you try to add
special cases for some code patterns by adding heuristics, those
heuristics now define the line and would have to become part of the
language specification.

More generally, the drawback of this kind of pattern recognition is that
there's an infinite pool of equivalent patterns to recognize, and
seemingly innocuous changes to a CTFEable function could break its
CTFEablility if they happen to cross the invisible boundary.

I'm just trying to point out the drawbacks of too clever heuristics. If
such an heuristic is used, I think it should be limited in scope and
well documented. Unfortunately, that means you'll still have to care
about writing code in a way that fits the documented pattern. It'd be
much easier to reason about CTFEability if the pattern had to be
encapsulated in its own function.


The heuristic is: one pointer comparison in each direction, connected by && or ||. No restriction on the pointer expressions, except that they must have no side-effects.

That covers most legitimate cases.
The ones it doesn't cover are:
- doing two interleaved isInside() comparisons:

p1 >= q1 && s1 >= r1 && p2 < q2 && s2 < r2
which needs to be rewritten as:
(p1 >= q1 && p2 < q2) && (s1 >= r1 && s2 < r2)

- saving two one-side compares, and then not using them for _anything_ except an && or ||
---> this is a fundamental limitation

- calling two functions which each return a one-side-compare:
bool cmp(void *a, void *b) { return a<b);
cmp(p1, q1) && cmp(q2, p2)

----> this one could actually be done, because it would only be legal to call such a function from an && or ||. Implementation would be complicated though.

Reply via email to