www.digitalmars.com         C & C++   DMDScript  

D - Request for a feature or a bug?

reply MicroWizard <MicroWizard_member pathlink.com> writes:
I don't find anything in the documentation about that:
Should D make any run-time check whether a reference to an object is null
or not, before it calls a member function?

I wrote the attached program and it hangs up (CTRL-C can terminate :-)
if I left out the marked line.

Obviously there is a bug in my program in this case. The reference
variable was created only and no physical object.

I think it is a typical problem for C++ programmers when starting
to use D. First I tought the object instance will be created...

This bug can be caught only before the call is made to
I_don't_know_where, the CPU does not call the member where
the catch would also be possible.

A run-time check for null (with an exception thrown if needed)
would be fine or is any other solution?

Thanks in advance,
Tamas

--------------------------
import c.stdio;

class xRecord{
int b;

this() {b=3;}
void set(int x)
{
if(this==null)
{
throw new Error("OOOooooppppsss !");
}
else
{
printf("The value of _this_: %p\n",this);
}
b=x;
}
}

void main(char[][] args)
{
xRecord xr2;
//    xr2=new xRecord();	//*********************************

printf("start\n");

if(xr2==null)
{
printf("xr2 is null\n");
}
else
{
printf("xr2 is: %p\n",xr2);
}

xr2.set(10); // hangs up if xr2 equals to null

printf("finish\n");
}
--------------------------------

Tamas Nagy
MicroWizard Ltd.
Hungary

microwizard .ax.hu
May 05 2002
parent reply "Walter" <walter digitalmars.com> writes:
Null pointer dereferences should GP fault, not hang. Since the hardware does
the check for free, there's no profit to adding it into the language.
Remember, you can write exception handlers to catch GP fault exceptions.

"MicroWizard" <MicroWizard_member pathlink.com> wrote in message
news:ab388k$2ao0$1 digitaldaemon.com...
 I don't find anything in the documentation about that:
 Should D make any run-time check whether a reference to an object is null
 or not, before it calls a member function?

 I wrote the attached program and it hangs up (CTRL-C can terminate :-)
 if I left out the marked line.

 Obviously there is a bug in my program in this case. The reference
 variable was created only and no physical object.

 I think it is a typical problem for C++ programmers when starting
 to use D. First I tought the object instance will be created...

 This bug can be caught only before the call is made to
 I_don't_know_where, the CPU does not call the member where
 the catch would also be possible.

 A run-time check for null (with an exception thrown if needed)
 would be fine or is any other solution?

 Thanks in advance,
 Tamas

 --------------------------
 import c.stdio;

 class xRecord{
 int b;

 this() {b=3;}
 void set(int x)
 {
 if(this==null)
 {
 throw new Error("OOOooooppppsss !");
 }
 else
 {
 printf("The value of _this_: %p\n",this);
 }
 b=x;
 }
 }

 void main(char[][] args)
 {
 xRecord xr2;
 //    xr2=new xRecord(); //*********************************

 printf("start\n");

 if(xr2==null)
 {
 printf("xr2 is null\n");
 }
 else
 {
 printf("xr2 is: %p\n",xr2);
 }

 xr2.set(10); // hangs up if xr2 equals to null

 printf("finish\n");
 }
 --------------------------------

 Tamas Nagy
 MicroWizard Ltd.
 Hungary

 microwizard .ax.hu

May 05 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:ab426r$310j$3 digitaldaemon.com...

 Null pointer dereferences should GP fault, not hang. Since the hardware

 the check for free, there's no profit to adding it into the language.
 Remember, you can write exception handlers to catch GP fault exceptions.

But still... not every hardware does, and even then, I'd like to see the message explaining what REALLY happened, and not just another cryptic GP error "info".
May 05 2002
next sibling parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:ab45q3$39j$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:ab426r$310j$3 digitaldaemon.com...

 Null pointer dereferences should GP fault, not hang. Since the hardware

 the check for free, there's no profit to adding it into the language.
 Remember, you can write exception handlers to catch GP fault exceptions.

But still... not every hardware does, and even then, I'd like to see the message explaining what REALLY happened, and not just another cryptic GP error "info".

Yep. "Null pointer dereferenced at line #25: mynullpointer->DoSomething();" would be a thousand times more valuable than "MYDAPP.EXE caused a general protection fault at address 34EF:4FEC: read of address 0000:0000"... -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
May 05 2002
next sibling parent Keith Ray <k1e2i3t4h5r6a7y 1m2a3c4.5c6o7m> writes:
In article <ab4729$4qa$1 digitaldaemon.com>,
 "OddesE" <OddesE_XYZ hotmail.com> wrote:

 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:ab45q3$39j$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:ab426r$310j$3 digitaldaemon.com...

 Null pointer dereferences should GP fault, not hang. Since the hardware

 the check for free, there's no profit to adding it into the language.
 Remember, you can write exception handlers to catch GP fault exceptions.

But still... not every hardware does, and even then, I'd like to see the message explaining what REALLY happened, and not just another cryptic GP error "info".

Yep. "Null pointer dereferenced at line #25: mynullpointer->DoSomething();" would be a thousand times more valuable than "MYDAPP.EXE caused a general protection fault at address 34EF:4FEC: read of address 0000:0000"...

Have you ever read the following... <http://www.smalltalkchronicles.net/edition2-1/null_object_pattern.htm> snip: If you answer nil in Objective-C, the nil that is returned is, in some respects, a lot like Smalltalkšs nil, except that instead of the nil generating exceptions when you message it, it just silently eats the messages. Thus, in Objective-C, nil acts more like a "black hole". It is emptiness. It is nothingness. If you send anything to nil, nil is all you get back. No exceptions. No return values. Nothing. Obviously, if we wanted this same behavior in Smalltalk, we would simply override the #doesNotUnderstand: instance message of the UndefinedObject class to just answer self. The interesting thing is that Objective-C has had a silent 'nil' for over a decade, and it didn't prevent a bunch of good software from being written... -- C. Keith Ray <http://homepage.mac.com/keithray/xpminifaq.html>
May 05 2002
prev sibling next sibling parent reply Jonathan Andrew <jon ece.arizona.edu> writes:
OddesE wrote:

 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:ab45q3$39j$1 digitaldaemon.com...
 
"Walter" <walter digitalmars.com> wrote in message
news:ab426r$310j$3 digitaldaemon.com...


Null pointer dereferences should GP fault, not hang. Since the hardware

the check for free, there's no profit to adding it into the language.
Remember, you can write exception handlers to catch GP fault exceptions.

the message explaining what REALLY happened, and not just another cryptic GP error "info".

Yep. "Null pointer dereferenced at line #25: mynullpointer->DoSomething();" would be a thousand times more valuable than "MYDAPP.EXE caused a general protection fault at address 34EF:4FEC: read of address 0000:0000"... -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail

That would be a fantastic idea, but does D compile the source code line information in with the program? It would be nice if that were an option during compile time, and if you wanted that information (along with the added bloat) you would get nice error messages, perfect for debugging, then for memory-constrained apps you could leave that info out? Has this been discussed yet?
May 05 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Jonathan Andrew" <jon ece.arizona.edu> wrote in message
news:3CD601AB.7030707 ece.arizona.edu...

 That would be a fantastic idea, but does D compile the source code line
 information in with the program? It would be nice if that were an option
 during compile time, and if you wanted that information (along with the
 added bloat) you would get nice error messages, perfect for debugging,
 then for memory-constrained apps you could leave that info out? Has this
   been discussed yet?

Of course this should only happen in debug builds! As for the line info... well, assertions do store it (try assert(false)), so why not other exceptions that are inserted by the compiler?
May 05 2002
parent reply "Stephen Fuld" <s.fuld.pleaseremove att.net> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:ab53vt$thl$1 digitaldaemon.com...
 "Jonathan Andrew" <jon ece.arizona.edu> wrote in message
 news:3CD601AB.7030707 ece.arizona.edu...

 That would be a fantastic idea, but does D compile the source code line
 information in with the program? It would be nice if that were an option
 during compile time, and if you wanted that information (along with the
 added bloat) you would get nice error messages, perfect for debugging,
 then for memory-constrained apps you could leave that info out? Has this
   been discussed yet?

Of course this should only happen in debug builds! As for the line info... well, assertions do store it (try assert(false)), so why not other exceptions that are inserted by the compiler?

As long as you don't care if it is precisely accurate. With heavy optimizaton, it sometimes isn't at all obvious to which source line a particular instruction belongs (for example, it might be more than one) and it is certainly no longer the case that a contiguous group of instructions belongs to a single source line. This makes keeping source line number much more costly to implement. -- - Stephen Fuld e-mail address disguised to prevent spam
May 06 2002
next sibling parent Jonathan Andrew <jon ece.arizona.edu> writes:

As for the line info... well, assertions do store it (try assert(false)), so why not other exceptions that are inserted by the compiler?

As long as you don't care if it is precisely accurate. With heavy optimizaton, it sometimes isn't at all obvious to which source line a particular instruction belongs (for example, it might be more than one) and it is certainly no longer the case that a contiguous group of instructions belongs to a single source line. This makes keeping source line number much more costly to implement. -- - Stephen Fuld e-mail address disguised to prevent spam

In debug builds, heavy optimization isn't as much a priority as functional code (unless you are a real speed freak) so IMHO, I think this concern shouldn't outweigh the benefits of having that kind of information available.
May 06 2002
prev sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"Stephen Fuld" <s.fuld.pleaseremove att.net> wrote in message
news:ab6g1p$2gau$1 digitaldaemon.com...

 As long as you don't care if it is precisely accurate.  With heavy
 optimizaton, it sometimes isn't at all obvious to which source line a
 particular instruction belongs (for example, it might be more than one)

 it is certainly no longer the case that a contiguous group of instructions
 belongs to a single source line.  This makes keeping source line number

 more costly to implement.

When optimizations are on, all assert() are removed. What I proposed is that compiler silently inserts an assert (with properly modified error message) before each deferencing. Since asserts are already implemented, no additional work is needed to make line numbers work.
May 06 2002
prev sibling parent "Walter" <walter digitalmars.com> writes:
"Jonathan Andrew" <jon ece.arizona.edu> wrote in message
news:3CD601AB.7030707 ece.arizona.edu...
 That would be a fantastic idea, but does D compile the source code line
 information in with the program?

Yes.
 It would be nice if that were an option
 during compile time,

-g
 and if you wanted that information (along with the
 added bloat) you would get nice error messages, perfect for debugging,
 then for memory-constrained apps you could leave that info out? Has this
   been discussed yet?

If you run a D compiled program under a debugger, and it triggers a GP fault, the debugger will pop up with the cursor on the source line that failed.
May 12 2002
prev sibling parent "Walter" <walter digitalmars.com> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:ab4729$4qa$1 digitaldaemon.com...
 Yep. "Null pointer dereferenced at line #25:

 would be a thousand times more valuable than "MYDAPP.EXE caused a general
 protection fault at address 34EF:4FEC: read of address 0000:0000"...

That's basically what happens when you run the app under the debugger. You can also see the call stack, etc.
May 10 2002
prev sibling next sibling parent reply Russell Borogove <kaleja estarcion.com> writes:
Pavel Minayev wrote:
 "Walter" <walter digitalmars.com> wrote in message
 news:ab426r$310j$3 digitaldaemon.com...
 
 
Null pointer dereferences should GP fault, not hang. Since the hardware

does
the check for free, there's no profit to adding it into the language.
Remember, you can write exception handlers to catch GP fault exceptions.

But still... not every hardware does, and even then, I'd like to see the message explaining what REALLY happened, and not just another cryptic GP error "info".

Can we get Walter to standardize an exception object to catch general protection faults? Then every developer could display the GPF to the user in the way they found most useful. -R
May 05 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Russell Borogove" <kaleja estarcion.com> wrote in message
news:3CD5AEF0.5040404 estarcion.com...

 Can we get Walter to standardize an exception object
 to catch general protection faults? Then every developer
 could display the GPF to the user in the way they found
 most useful.

By the way, I wonder if all systems that D might get ported to support GPF?.. =)
May 05 2002
prev sibling next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:ab45q3$39j$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:ab426r$310j$3 digitaldaemon.com...
 Null pointer dereferences should GP fault, not hang. Since the hardware

 the check for free, there's no profit to adding it into the language.
 Remember, you can write exception handlers to catch GP fault exceptions.


Correct, the 16 bit PC did not, which made the PC a terrible platform for code development. That's why I, as much as possible, developed 16 bit code using OS/2 1.1 and using 286 DOS extenders. When all was working, then I built a real mode version.
 and even then, I'd like to see
 the message explaining what REALLY happened, and not just another cryptic
 GP error "info".

All I need is having it pop up in the debugger with the offending code position highlighted.
May 06 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:ab5mau$1io7$1 digitaldaemon.com...

 All I need is having it pop up in the debugger with the offending code
 position highlighted.

We are yet to see a debugger (probably integrated into the IDE) for D. This is something that will probably not happen in near future. On other hand, inserting a simple assert(obj) check is a matter of minutes, and would greatly simplify things to us now, and to those guys - like me - who still prefer good old command-line.
May 06 2002
parent "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:ab5rsa$1oed$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:ab5mau$1io7$1 digitaldaemon.com...
 All I need is having it pop up in the debugger with the offending code
 position highlighted.

for D. This is something that will probably not happen in near future. On other hand, inserting a simple assert(obj) check is a matter of minutes, and would greatly simplify things to us now, and to those guys - like me - who still prefer good old command-line.

D works with common debuggers, like Windbg.exe.
May 19 2002
prev sibling parent reply Alexander Lahmann <info elco-pro.de> writes:
Pavel Minayev wrote:
 Null pointer dereferences should GP fault, not hang. Since the hardware

 the check for free, there's no profit to adding it into the language.
 Remember, you can write exception handlers to catch GP fault exceptions.

the message explaining what REALLY happened, and not just another cryptic GP error "info".

pointer is a valid pointer. When Walter want s to implement it, it should be optional ... or you should be able to turn it on/off by a pragma or something like that. Best regards, Mark Junker
May 12 2002
next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"Alexander Lahmann" <info elco-pro.de> wrote in message
news:3CDEC72D.D879A4AB elco-pro.de...

 There are lots of hardware platforms (even x86) out there where a NULL
 pointer is a valid pointer.

However, I'm not aware of any platform where null is a legal object reference - and I was talking only about objects. Of course, traditional pointers are left for low-level tasks, and shouldn't have any checks on them.
May 12 2002
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
"Alexander Lahmann" <info elco-pro.de> wrote in message
news:3CDEC72D.D879A4AB elco-pro.de...
 There are lots of hardware platforms (even x86) out there where a NULL
 pointer is a valid pointer. When Walter want
 s to implement it, it should be optional ... or you should be able to
 turn it on/off by a pragma or something like that.

Just checking for null pointers on the x86 was rarely good enough. Many invalid pointers have random values which would scramble DOS's data areas.
May 19 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:ac93fb$1kvn$1 digitaldaemon.com...

 Just checking for null pointers on the x86 was rarely good enough. Many
 invalid pointers have random values which would scramble DOS's data areas.

Oh, I see now. All object references on stack are undefined, anyhow, so null-check won't help much...
May 19 2002
prev sibling next sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
I disagree.  For one, some architectures (68K, Playstation 1, 6502) cannot
generate hardware GP faults so such errors will go undetected.

I think it would be a valuable debugging tool to throw on dereference of
null object references.  Obviously only in debug builds, or perhaps only in
"extra debug" builds...?

In any case I see this as an implementation issue, not a core language
issue.

Sean

"Walter" <walter digitalmars.com> wrote in message
news:ab426r$310j$3 digitaldaemon.com...
 Null pointer dereferences should GP fault, not hang. Since the hardware

 the check for free, there's no profit to adding it into the language.
 Remember, you can write exception handlers to catch GP fault exceptions.

May 06 2002
parent reply "Stephen Fuld" <s.fuld.pleaseremove att.net> writes:
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:ab5apj$16r5$1 digitaldaemon.com...
 I disagree.  For one, some architectures (68K, Playstation 1, 6502) cannot
 generate hardware GP faults so such errors will go undetected.

 I think it would be a valuable debugging tool to throw on dereference of
 null object references.  Obviously only in debug builds, or perhaps only

 "extra debug" builds...?

If nil is, in fact, equal to zero, then we are talking about typically one extra instruction, and on modern CPUs that instruction can usually be done in parallel with the start of whatever is next, so the cost is pretty minimal. I'm not sure it shouldn't be the default to keep those checks in, but there is certainly no need for "extra debug" flags. -- - Stephen Fuld e-mail address disguised to prevent spam
May 06 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Stephen Fuld" <s.fuld.pleaseremove att.net> wrote in message
news:ab6g1r$2gau$2 digitaldaemon.com...

 If nil is, in fact, equal to zero, then we are talking about typically one
 extra instruction, and on modern CPUs that instruction can usually be done
 in parallel with the start of whatever is next, so the cost is pretty

Something more useful could be done in parallel instead of null-check.
 minimal.  I'm not sure it shouldn't be the default to keep those checks

 but there is certainly no need for "extra debug" flags.

Yep, just "debug" is fine. =) Personally, I do not want those checks in release version - I'd rather have it running at full speed. The best approach, IMO, is to follow the way array bounds checking is done - default ON in debug version, default OFF in release version, and an option to change it if necessary...
May 06 2002
parent "Stephen Fuld" <s.fuld.pleaseremove att.net> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:ab7ilk$k17$1 digitaldaemon.com...
 "Stephen Fuld" <s.fuld.pleaseremove att.net> wrote in message
 news:ab6g1r$2gau$2 digitaldaemon.com...

 If nil is, in fact, equal to zero, then we are talking about typically


 extra instruction, and on modern CPUs that instruction can usually be


 in parallel with the start of whatever is next, so the cost is pretty

Something more useful could be done in parallel instead of null-check.
 minimal.  I'm not sure it shouldn't be the default to keep those checks

 but there is certainly no need for "extra debug" flags.

Yep, just "debug" is fine. =) Personally, I do not want those checks in release version - I'd rather

 it running at full speed. The best approach, IMO, is to follow the way
 array bounds checking is done - default ON in debug version, default OFF
 in release version, and an option to change it if necessary...

I don't have a problem with that. -- - Stephen Fuld e-mail address disguised to prevent spam
May 06 2002
prev sibling parent reply MicroWizard <MicroWizard_member pathlink.com> writes:
In article <ab426r$310j$3 digitaldaemon.com>, Walter says...
Null pointer dereferences should GP fault, not hang. Since the hardware does
the check for free, there's no profit to adding it into the language.
Remember, you can write exception handlers to catch GP fault exceptions.

It shouldn't hang but it actually does. Is it a bug?
May 07 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"MicroWizard" <MicroWizard_member pathlink.com> wrote in message
news:ab93ob$21qo$1 digitaldaemon.com...
 In article <ab426r$310j$3 digitaldaemon.com>, Walter says...
Null pointer dereferences should GP fault, not hang. Since the hardware


the check for free, there's no profit to adding it into the language.
Remember, you can write exception handlers to catch GP fault exceptions.

It shouldn't hang but it actually does. Is it a bug?

Is the pointer really null? Often dereferencing a pointer that is not null, but just contains garbage can cause a hang. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
May 07 2002
parent MicroWizard <MicroWizard_member pathlink.com> writes:
Null pointer dereferences should GP fault, not hang. Since the hardware


the check for free, there's no profit to adding it into the language.
Remember, you can write exception handlers to catch GP fault exceptions.

It shouldn't hang but it actually does. Is it a bug?

Is the pointer really null? Often dereferencing a pointer that is not null, but just contains garbage can cause a hang.

Clear and short code. After few second the "standard" GPF appears almost always. Tamas ---------------------- import c.stdio; class xRecord{ int b; this() {b=3;} } void main(char[][] args) { xRecord xr2; // xr2=new xRecord(); //******************************** if(xr2==null) { printf("xr2 is null\n"); } xr2.set(10); // hangs up if xr2 equals to null }
May 07 2002