Uh... destructors?

Steven Schveighoffer schveiguy at yahoo.com
Wed Feb 23 13:51:03 PST 2011


On Wed, 23 Feb 2011 16:40:22 -0500, bearophile <bearophileHUGS at lycos.com>  
wrote:

> Steven Schveighoffer:
>
>> That's not what your example showed.  It showed comparing two allocated
>> pointers *outside* a pure function, and expected them to be equal.  I  
>> see
>> that as disallowing all pointer comparisons.
>
> My first examples were not so good, I am sorry :-) Thank you for not  
> ignoring my posts despite that.
>
> The idea was that if you allocate memory inside a pure function, then  
> the result of this memory allocation is a @transparent  
> pointer/reference. And that a @transparent pointer/reference can't be  
> read (but you are allowed to dereference it, overwrite it, etc).
>
> So this is OK, because the transparency of the pointer is respected:
>
> pure @transparent(int*) foo() {
>   return new int; // allocates just one int on the heap
> }
> void main() {
>   @transparent int* i = foo(); // OK
>   *i = 10; // OK
> }

@transparent has little value outside a pure function, because the  
compiler does not expect to be able to perform pure optimizations on  
normal functions.  Right now, the only drawback you have shown of being  
able to compare such references is when that comparison is used as the  
return value for a pure function.  We can't continue to enforce the  
@transparent rules when they don't prevent problems, or else the language  
becomes too burdensome.

>> It also has some unpleasant effects.  For example, the object equality
>> operator does this:
>>
>> bool opEquals(Object o1, Object o2)
>> {
>>    if(o1 is o2)
>>      return true;
>>    ...
>> }
>>
>> So this optimization would be unavailable inside pure functions, no?  Or
>> require a dangerous cast?
>
>
> Ick.
> You can't give a @transparent Object to function that expects an Object,  
> because transparent references disallow something that you are allowed  
> to do on a not transparent reference/pointer:
>
>
> pure @transparent Object foo() {
>   return new Object();
> }
> void opEquals(Object o1, Object o2) {}
> void main() {
>   @transparent Object o = foo();
>   opEquals(o, o); // not allowed
> }

Once a reference gets out of a pure function, I think it should implicitly  
cast to a non-transparent reference, or else you have a huge mess.  I  
would not like to define @transparent versions of all functions.

The question is, shouldn't you be able to compare two objects inside a  
pure function?  I would think so.  Note that the comparison inside  
opEquals does not alter purity, it's just an optimization.

Then again, I don't think opEquals would be callable inside a pure  
function, since it's not pure itself.

Would something like o is null be allowed?

>> Would it be enough to just require this type of restriction in pure  
>> @safe
>> functions?
>
> I don't know.
>
> Currently @safe is a wrong name, it means means @memorySafe. So I think  
> that currently "@memorySafe" and "pure" are almost orthogonal concepts.

@safe is supposed to prevent using pointers.  But then again, the  
definition is a moving target.  I have a vague memory that really only  
pointer arithmetic is disallowed, comparison is allowed.

-Steve


More information about the Digitalmars-d mailing list