Aquivalent References as in C++?

Ali Çehreli acehreli at yahoo.com
Tue Apr 17 11:01:46 PDT 2012


On 04/17/2012 10:37 AM, Namespace wrote:
 >> Yes, you must because whetheer obj is null is only known at runtime.
 >
 > Yes, but if i forget the assert i get an Access Violation error with no
 > more informations. Problem is nobody knows _why_ he gets this error,
 > because the error message gives no information.

In order to get a meaningful error, the compiler would have to inject 
code that checked every access through a class reference. Unfortunately 
that would bring too much overhead and not be acceptable in a system 
language.

But it could be a part of the non-release builds. I don't have any idea 
how slow program would become if every class dereferencing would be 
checked against null like that. (?)

 > So it must be a better solution then to write in every method
 > "assert(obj_param !is null");".

Not in every method, but only in methods that actually dereference that 
pointer. Intermediate functions that simply pass the parameter to 
another function need not check the condition.

In the end, null references are a part of D. The code must be written in 
a way to accept it.

As an aside, enforce() may be more suitable and a little shorter:

   enforce(obj_param, "Even with a message");

Whether to use assert() or enforce() depends on the function.

 > Best of all solutions would be that a
 > special keyword, for example scope, ensure that lvalues would except but
 > _no_ null-references.

Yes, the keyword would be a little shorter than the assert() or 
enforce() above but D already has very many keywords. :)

Finally, actually it is possible to have bugs of the same sort even with 
references in C++:

// C++ code

struct S
{
     int i;

     S(int param_i)
         :
         i(param_i)
     {}
};

S * make_S(int i)
{
     return (i == 42) ? new S(i) : 0;
}

void use_S(const S & s)
{
     int i = s.i;
}

int main()
{
     use_S(*make_S(100));
}

The output is the same as in D:

Segmentation fault

So, as you see, neither C++ provide any help here.

C++'s references have these meanings:

* On the parameter list: "I would like to have a real object please." As 
seen above, it is so easy to violate that. The caller of use_S() 
realizes that a reference is needed and just dereferences the pointer at 
hand. See, the caller must ensure even in C++ that the pointer that is 
available is not NULL.

* On the return type: "What I give you is an alias to an existing 
object." Even this is a false promise without tool support, because the 
reference may be of an automatic local object.

Ali



More information about the Digitalmars-d-learn mailing list