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

Reply via email to