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