Pointer semantics in CTFE

Don nospam at nospam.com
Sat May 26 03:59:25 PDT 2012


On 26.05.2012 05:35, Walter Bright wrote:
> On 5/25/2012 8:24 PM, Don wrote:
>> The problem is, if pstart and pend point to the beginning and end of
>> an array,
>> then given another pointer q, there is AFAIK no defined way in C for
>> checking if
>> q is between pstart and pend, even though I'm sure everyone does it.
>> (eg, I
>> don't know how to implement memcpy otherwise).
>> If q is part of that array, (q >= pstart && q <= pend) is
>> well-defined, and
>> returns true.
>> But if it isn't part of that array, q >= pstart is undefined.
>>
>> In reality of course, if q is unrelated to the array then EITHER q <
>> pstart, OR
>> q > pend. So (q >= pstart && q <= pend) is ALWAYS false, and the
>> result is
>> completely predictable.
>
> If q is unrelated to the array, which you can tell because q, pstart,
> and pend must all refer to the same object that CTFE knows about, then
> you can have CTFE refuse to execute it.

Yes, that's what happens now. But that doesn't help the programmer.

If it is inside, no problem, the expression is true. But if it is not 
inside, the expression is not false -- it's a compile-time error.

So you can't use it as a test for if it is inside the same object.

I was confused about how memmove can work in C without relying on 
undefined behaviour. But I just read
http://www.cplusplus.com/reference/clibrary/cstring/memcpy/
which defines it in terms of an intermediate buffer.

So maybe, the current CTFE implementation is _exactly_ consistent with 
the C spec. If that's true, though, I find it pretty incredible that 
there is no way to find out if a pointers points a particular array, 
even if you have pointers to both the start and end of that array.

(OK, I guess you can iterate from start to end, checking for equality, 
but .. bleah .. it's a terrible abstraction inversion).




>
>
>> ie, the full expression can be well-defined even though its two
>> subexpressions
>> are not.
>>
>> This can be implemented.
>> Given an expression like q >= pstart, where p and q are unrelated,
>> it's possible
>> to make it have the value 'false_or_undefined'. If it is anded with
>> another
>> expression that is also false_or_undefined, and goes the other
>> direction ( q <=
>> pend) , then the whole thing is false. Otherwise, it generates an error.
>>
>> The reason it would have to be a special case is because of things like:
>> bool b = false;
>> q >= start && ( b = true, true) && q <= end
>> which is undefined because the result of the first comparison has been
>> stored.
>> So it would only be valid for
>> one-comparison-in-each-direction-anded-together
>> (and the equivalent for ||).
>
> I still don't think you need to make a special case for it. If upon
> initialization of q, pstart, and pend, CTFE makes a note of what memory
> object they are initialized from, then you can unambiguously tell if
> they still point within the same object or not.


More information about the Digitalmars-d mailing list