References in D

Chad J chadjoan at __spam.is.bad__gmail.com
Sat Oct 6 23:45:44 PDT 2012


On 10/07/2012 02:22 AM, David Piepgrass wrote:
>> void main()
>> {
>> void* x = a(b());
>> c();
>> while(goobledegook)
>> {
>> x = p();
>> d(x);
>> }
>> e(x); /+ Crash! x is null. +/
>> }
>>
>> Where did x's null value come from? Not a. Not p; the while loop
>> happened to be never executed. To say "b" would be closer, but still
>> imprecise. Actually it was created in the q() function that was called
>> by u() that was called by b() which then created a class that held the
>> null value and was passed to a() that then dereferenced the class and
>> returned the value stored in the class that happened to be null. nulls
>> create very non-local bugs, and that's why they frustrate me to no end
>> sometimes.
>
> Since this thread's attracted lots of commotion I thought I'd just drop
> by and +1 for non-nullable types, and +1 for your arguments.
>
> I keep wondering, though, if it is 'enough' to solve the null problem,
> or if it would be possible to devise a more general mechanism for
> solving other problems too, like say, the fact that certain integers
> have to always be positive, or if you want to go more general, that a
> certain relationship must hold between two structures...
>

I agree.

> Not having used D's invariants so far (well, I haven't used D itself for
> a real project actually)... what's stopping D's invariant mechanism from
> handling all this?
>
> http://dlang.org/class.html#invariants (as is typical of D
> documentation, this says nothing about invariants on structs, but the
> page about structs says that they support invariants with an X.)
>
> I mean, problems are detected at runtime this way, and slightly too
> late, but still, it would be better than most popular languages that
> can't do anything about nulls at all. Since D's devs don't even seem to
> have enough time to implement D as described in TDPL (published more
> than two years ago), I wouldn't expect to see this feature in the D
> language in the near future.

Invariants might work... create a proxy struct and then have assignment 
always check the invariant.  I don't like the idea that they get removed 
during release mode.  I'd like to be able to control which checks I pay 
for.  I think this might just mean that the important thing is 
overloading assignment to do checks, which could be done in principle, 
and this could work without invariants and thus give the desired control.

I just haven't had much luck creating proxy types in the past.  As of 
some months ago, D just wasn't there yet.  :(

In another post in this thread I mentioned something similar:

>
> It would be cool to have templates like this:
>
> 51.  bool isPrime(int val)
> 52.  {
> 53.      ...
> 54.  }
>
> 101. Watch!(int,&isPrime) primeNumber = primeGenerator();
> 102. primeNumber = 8;
> 103. doStuff();
> 104. checkPrime(primeNumber); /+ Crash! +/
> Error: checkPrime(primeNumber): primeNumber is not prime.
> primeNumber: isPrime returned false after assignment at
>   (foobar.d, line 102)
>
> ~or~
>
> 101. Constrain!(int,&isPrime) primeNumber = primeGenerator();
> 102. primeNumber = 8; /+ Crash! +/
> 103. doStuff();
> 104. checkPrime(primeNumber);
> foobar.d, line 102: isPrime returned false after assignment.
>
> For convenience one could define this:
> alias Constrain!(int,&isPrime) PrimeInt;

Maybe these could be turned on/off in release mode on a case-by-case 
basis.  I would probably leave the checks and tracking in always, with 
the one exception of code that has been shown (with profiling) to need 
the extra performance.



More information about the Digitalmars-d mailing list