March 02, 2012
Am I correct that trying to use an Object null results in undefined behavior?

    Object o = null;
    o.opCmp(new Object); // segmentation fault on my OSX machine

This seems a bit non-D-ish to me, as other bugs like this throw Errors (e.g. RangeError).

It would be nice if it would throw a NullPointerError or something like that, because I spent a long time trying to find a bug that crashed the program before writeln-debugging statements could be flushed.

NMS
March 02, 2012
On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:
> Am I correct that trying to use an Object null results in undefined behavior?
> 
>      Object o = null;
>      o.opCmp(new Object); // segmentation fault on my OSX machine
> 
> This seems a bit non-D-ish to me, as other bugs like this throw
> Errors (e.g. RangeError).
> 
> It would be nice if it would throw a NullPointerError or something like that, because I spent a long time trying to find a bug that crashed the program before writeln-debugging statements could be flushed.

It's defined. The operating system protects you. You get a segfault on *nix and an access violation on Windows. Walter's take on it is that there is no point in checking for what the operating system is already checking for - especially when it adds additional overhead. Plenty of folks disagree, but that's the way it is.

If you really care about checking for it, then just assert:

assert(obj !is null);

or

assert(obj);

(the second one will also call the object's invariant).

- Jonathan M Davis
March 02, 2012
On Friday, 2 March 2012 at 04:53:02 UTC, Jonathan M Davis wrote:
> On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:
>> Am I correct that trying to use an Object null results in
>> undefined behavior?
>> 
>>      Object o = null;
>>      o.opCmp(new Object); // segmentation fault on my OSX machine
>> 
>> This seems a bit non-D-ish to me, as other bugs like this throw
>> Errors (e.g. RangeError).
>> 
>> It would be nice if it would throw a NullPointerError or
>> something like that, because I spent a long time trying to find a
>> bug that crashed the program before writeln-debugging statements
>> could be flushed.
>
> It's defined. The operating system protects you. You get a segfault on *nix and
> an access violation on Windows.

False.

-----------------------
import std.stdio;

class Foo
{
    final void bar()
    {
        writeln("I'm null!");
    }
}

void main()
{
    Foo foo;
    foo.bar();
}
-----------------------

% dmd test.d -O -release -inline
% ./test
I'm null!
%

-----------------------

You only get an error if there is a memory access involved (vtable, member data etc.)

March 02, 2012
"Peter Alexander" <peter.alexander.au@gmail.com> wrote in message news:vicaibqyaerogseqsjbe@forum.dlang.org...
>>
>> It's defined. The operating system protects you. You get a segfault on
>> *nix and
>> an access violation on Windows.
>
> False.
>
> [snip]
>
> You only get an error if there is a memory access involved (vtable, member data etc.)
>

It _is_ defined, you get an access violation whenever there's a dereference. Yes, you can call some types of member functions without any dereferences, but this is alse well defined and sometimes quite useful.


March 02, 2012
On 2012-03-02 10:22, Peter Alexander wrote:
> On Friday, 2 March 2012 at 04:53:02 UTC, Jonathan M Davis wrote:
>> On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:
>>> Am I correct that trying to use an Object null results in
>>> undefined behavior?
>>>
>>> Object o = null;
>>> o.opCmp(new Object); // segmentation fault on my OSX machine
>>>
>>> This seems a bit non-D-ish to me, as other bugs like this throw
>>> Errors (e.g. RangeError).
>>>
>>> It would be nice if it would throw a NullPointerError or
>>> something like that, because I spent a long time trying to find a
>>> bug that crashed the program before writeln-debugging statements
>>> could be flushed.
>>
>> It's defined. The operating system protects you. You get a segfault on
>> *nix and
>> an access violation on Windows.
>
> False.
>
> -----------------------
> import std.stdio;
>
> class Foo
> {
> final void bar()
> {
> writeln("I'm null!");
> }
> }
>
> void main()
> {
> Foo foo;
> foo.bar();
> }
> -----------------------
>
> % dmd test.d -O -release -inline
> % ./test
> I'm null!
> %
>
> -----------------------
>
> You only get an error if there is a memory access involved (vtable,
> member data etc.)
>

I never thought about that.

-- 
/Jacob Carlborg
March 02, 2012
On Friday, March 02, 2012 11:56:52 Jacob Carlborg wrote:
> I never thought about that.

It's the same in C++. I was quite surprised when I first ran into it. But as Daniel points out, the behavior is still defined, just less expected. If you actually use this (or any member variable, since that would use this) inside of that member function though, you'll get a segfault just like if it had been dereferenced before calling the function like it would be with a virtual function.

- Jonathan M Davis
March 02, 2012
On 03/02/2012 10:22 AM, Peter Alexander wrote:
> You only get an error if there is a memory access involved (vtable,
> member data etc.)
>

In non-release mode you get an assertion failure.
March 02, 2012
On Friday, 2 March 2012 at 09:22:28 UTC, Peter Alexander wrote:
> You only get an error if there is a memory access involved (vtable, member data etc.)

By the way, my favorite application of that in C++ is debug helper member functions (think: using DMD's toChar() in GDB), which don't crash when invoked on a null pointer by checking if (this == 0) before accessing member variables.

David
March 02, 2012
On 2012-03-02 12:05, Jonathan M Davis wrote:
> On Friday, March 02, 2012 11:56:52 Jacob Carlborg wrote:
>> I never thought about that.
>
> It's the same in C++. I was quite surprised when I first ran into it. But as
> Daniel points out, the behavior is still defined, just less expected. If you
> actually use this (or any member variable, since that would use this) inside
> of that member function though, you'll get a segfault just like if it had been
> dereferenced before calling the function like it would be with a virtual
> function.
>
> - Jonathan M Davis

Yeah, that makes sense. A final method, not accessing "this", would be just as a static method. Which is like a free function scoped in a class.

-- 
/Jacob Carlborg
March 02, 2012
Le 02/03/2012 05:51, Jonathan M Davis a écrit :
> On Friday, March 02, 2012 05:37:46 Nathan M. Swan wrote:
>> Am I correct that trying to use an Object null results in
>> undefined behavior?
>>
>>       Object o = null;
>>       o.opCmp(new Object); // segmentation fault on my OSX machine
>>
>> This seems a bit non-D-ish to me, as other bugs like this throw
>> Errors (e.g. RangeError).
>>
>> It would be nice if it would throw a NullPointerError or
>> something like that, because I spent a long time trying to find a
>> bug that crashed the program before writeln-debugging statements
>> could be flushed.
>
> It's defined. The operating system protects you. You get a segfault on *nix and
> an access violation on Windows. Walter's take on it is that there is no point
> in checking for what the operating system is already checking for - especially
> when it adds additional overhead. Plenty of folks disagree, but that's the way
> it is.
>

The assertion that it has overhead isn't true.You'll find solutions without overhead (using libsigsegv in druntime for example).

BTW, object should be non nullable by default, if you ask me. The drawback of null is way bigger than any benefit.
« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10 11
Top | Discussion index | About this forum | D home