www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Error: null dereference in function _Dmain

reply "Namespace" <rswhite4 googlemail.com> writes:
I'm getting this with this code: http://dpaste.dzfl.pl/55f83be6
Can someone explain me, _why_ i get this error? o.O
I thought D cannot detect null references by itself.
Jul 02 2012
next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
On Monday, 2 July 2012 at 15:55:03 UTC, Namespace wrote:
 I'm getting this with this code: http://dpaste.dzfl.pl/55f83be6
 Can someone explain me, _why_ i get this error? o.O
 I thought D cannot detect null references by itself.

Can't check now. But if you get this during runtime, D does detect this resp. the hardware does.
Jul 02 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
On Monday, 2 July 2012 at 16:19:08 UTC, Tobias Pankrath wrote:
 On Monday, 2 July 2012 at 15:55:03 UTC, Namespace wrote:
 I'm getting this with this code: http://dpaste.dzfl.pl/55f83be6
 Can someone explain me, _why_ i get this error? o.O
 I thought D cannot detect null references by itself.

Can't check now. But if you get this during runtime, D does detect this resp. the hardware does.

I get this at compile time.
Jul 02 2012
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, July 02, 2012 17:55:01 Namespace wrote:
 I'm getting this with this code: http://dpaste.dzfl.pl/55f83be6
 Can someone explain me, _why_ i get this error? o.O
 I thought D cannot detect null references by itself.

You didn't actually list what error you're seeing. The error that I'm seeing (which may differ from yours' because I'm on the latest master, not 2.059, and you're probably on 2.059) is q.d(87): Error: constructor q.NotNull!(Foo).NotNull.this is not callable because it is annotated with disable And that error is being hit, because you're specifically trying to instatiate your NotNull!Foo with a null literal, and you disabled the constructor which would take typeof(null). The compiler isn't detecting any null references at all. It's complaining about your attempted use of a disabled constructor. - Jonathan M Davis
Jul 02 2012
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/02/2012 11:36 AM, Jonathan M Davis wrote:

 By the way, it's pointless to compile with both -w and -wi. -wi makes 

 that warnings are displayed without stopping compilation. -w makes it 

 warnings are displayed and treated as errors (so they stop 

 one or the other. I don't know which the compiler picks if you give 

 but it's going to have to pick one or the other, and it may not pick 

 that you want.

Then why is the documentation so misleading: -w enable warnings -wi enable informational warnings (i.e. compilation still proceeds normally) http://dlang.org/dmd-linux.html Me not know English good, but -wi sounds very much different from -w. :-T Further, both -w and -wi link to the following page, which does not mention -wi at all: http://dlang.org/warnings.html Sorry for whining... :( Ali
Jul 02 2012
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/02/2012 11:36 AM, Jonathan M Davis wrote:

 By the way, it's pointless to compile with both -w and -wi. -wi makes 

 that warnings are displayed without stopping compilation. -w makes it 

 warnings are displayed and treated as errors (so they stop 

 one or the other. I don't know which the compiler picks if you give 

 but it's going to have to pick one or the other, and it may not pick 

 that you want.

I have tested this: The one that is specified last on the command line takes effect: int main() { return 0; return 0; // Warning: statement is not reachable } $ dmd deneme.d # compiles without any diagnostics $ dmd deneme.d -w # breaks compilation $ dmd deneme.d -wi -w # ditto $ dmd deneme.d -wi # warns but compiles $ dmd deneme.d -w -wi # ditto Ali
Jul 02 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 You didn't actually list what error you're seeing. The error 
 that I'm seeing
 (which may differ from yours' because I'm on the latest master, 
 not 2.059, and
 you're probably on 2.059) is

 q.d(87): Error: constructor q.NotNull!(Foo).NotNull.this is not 
 callable
 because it is annotated with  disable

 And that error is being hit, because you're specifically trying 
 to instatiate
 your NotNull!Foo with a null literal, and you disabled the 
 constructor which
 would take typeof(null). The compiler isn't detecting any null 
 references at
 all. It's complaining about your attempted use of a disabled 
 constructor.

 - Jonathan M Davis

This code: http://dpaste.dzfl.pl/a0939681 prints dmd -w -wi -O -property -unittest -debug -of"not_null" "not_null.d" (im Verzeichnis: D:\D\D_Scripts\Test3) not_null.d(106): Error: null dereference in function _Dmain not_null.d(103): Error: null dereference in function _Dmain Kompilierung fehlgeschlagen. And even without disable this(typeof(null)); I get the same errors.
Jul 02 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, July 02, 2012 19:36:21 Namespace wrote:
 You didn't actually list what error you're seeing. The error
 that I'm seeing
 (which may differ from yours' because I'm on the latest master,
 not 2.059, and
 you're probably on 2.059) is
 
 q.d(87): Error: constructor q.NotNull!(Foo).NotNull.this is not
 callable
 because it is annotated with  disable
 
 And that error is being hit, because you're specifically trying
 to instatiate
 your NotNull!Foo with a null literal, and you disabled the
 constructor which
 would take typeof(null). The compiler isn't detecting any null
 references at
 all. It's complaining about your attempted use of a disabled
 constructor.
 
 - Jonathan M Davis

This code: http://dpaste.dzfl.pl/a0939681 prints dmd -w -wi -O -property -unittest -debug -of"not_null" "not_null.d" (im Verzeichnis: D:\D\D_Scripts\Test3) not_null.d(106): Error: null dereference in function _Dmain not_null.d(103): Error: null dereference in function _Dmain Kompilierung fehlgeschlagen. And even without disable this(typeof(null)); I get the same errors.

Well, I'm getting q.d(111): Error: no identifier for declarator t q.d(111): Error: found 'in' when expecting ';' due to your erroneous use of in a foreach loop instead of ;, but with that fixed I see Error: null dereference in function _Dmain q.d(103): Error: null dereference in function _Dmain which refers to test_not_null_foo(f1); which is a very weird error. test_not_null_foo takes a NotNull!Foo, not a Foo, and f1 is a Foo, and you haven't defined an implicit conversion from Foo to NotNull!Foo, so it should give an error about NotNull!Foo not being Foo. If you compile without -O, this code compiles without error, which is wrong. And if you compile with -O, you get the weird null dereference error. So, I think that there are two bugs here, both of them related to alias this, and one of them related to -O. Both should be reported ( http://d.puremagic.com/issues ), though ideally the code would be reduced to a minimal test case before doing so. By the way, you're handling classes incorrectly in your NotNull struct. isPointer!T is false for classes, so your Ptr function is returning a pointer to a class rather than a class. You need is(T == class) if you want to test whether T is a class. You seem to have created isObject to try and solve that problem, but isObject is going to give you funny results if T isn't a class but does have an alias this which converts to one. However, if you fix it so that Ptr returns an inout(T) for classes like it should, dmd seems to hit 100% CPU and grow in memory until the OS kills it. So, you're definitely hitting a bug with alias this here, but I don't know if that's a third bug or something else. I recall there being a recent bug report about the compiler running out of memory in a similar situation, but I'd have to go digging for it to be sure. By the way, it's pointless to compile with both -w and -wi. -wi makes it so that warnings are displayed without stopping compilation. -w makes it so that warnings are displayed and treated as errors (so they stop compilation). Pick one or the other. I don't know which the compiler picks if you give it both, but it's going to have to pick one or the other, and it may not pick the one that you want. - Jonathan M Davis
Jul 02 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 Well, I'm getting

 q.d(111): Error: no identifier for declarator t
 q.d(111): Error: found 'in' when expecting ';'

 due to your erroneous use of in a foreach loop instead of ;,

Sorry, that comes of my little compiler hack, as you can see here: http://forum.dlang.org/thread/rbltrlxsogrfxjzqfpxe forum.dlang.org?page=3 and here, if you like to read my mother language ;) http://blog.rswhite.de/archives/791
 but with that
 fixed I see

 Error: null dereference in function _Dmain
 q.d(103): Error: null dereference in function _Dmain

 which refers to

 test_not_null_foo(f1);

 which is a very weird error. test_not_null_foo takes a 
 NotNull!Foo, not a Foo,
 and f1 is a Foo, and you haven't defined an implicit conversion 
 from Foo to
 NotNull!Foo, so it should give an error about NotNull!Foo not 
 being Foo.

I have, as you can see here: [code] property NotNull!(Foo) GetNN() { return this._nnf; } alias GetNN this; [/code] line 75 in my DPaste code.
 If you compile without -O, this code compiles without error, 
 which is wrong. And
 if you compile with -O, you get the weird null dereference 
 error.

great!
 By the way, you're handling classes incorrectly in your NotNull 
 struct.
 isPointer!T is false for classes, so your Ptr function is 
 returning a pointer
 to a class rather than a class. You need is(T == class) if you 
 want to test
 whether T is a class. You seem to have created isObject to try 
 and solve that
 problem, but isObject is going to give you funny results if T 
 isn't a class
 but does have an alias this which converts to one.

Thanks! I will fix it.
 However, if you fix it so that Ptr returns an inout(T) for 
 classes like it
 should, dmd seems to hit 100% CPU and grow in memory until the 
 OS kills it.
 So, you're definitely hitting a bug with alias this here, but I 
 don't know if
 that's a third bug or something else. I recall there being a 
 recent bug report
 about the compiler running out of memory in a similar 
 situation, but I'd have
 to go digging for it to be sure.

That's a bug i posted a while ago and i thougth that kenjii fix it in 2.060, or not? The compiler create an infinite loop and convert from Foo to NotNull!(Foo) and back and so on. If you create _one_ instance and returns them as pointer (or cast them as pointer, as you can se at my opCast method) the compiler breaks the conversion immediately. A little hack i detected and help me to realize the NotNull struct as i want. :)
 By the way, it's pointless to compile with both -w and -wi. -wi 
 makes it so
 that warnings are displayed without stopping compilation. -w 
 makes it so that
 warnings are displayed and treated as errors (so they stop 
 compilation). Pick
 one or the other. I don't know which the compiler picks if you 
 give it both,
 but it's going to have to pick one or the other, and it may not 
 pick the one
 that you want.

 - Jonathan M Davis

Thansk again, i will fix it too.
Jul 02 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, July 02, 2012 20:52:19 Namespace wrote:
 Well, I'm getting
 
 q.d(111): Error: no identifier for declarator t
 q.d(111): Error: found 'in' when expecting ';'
 
 due to your erroneous use of in a foreach loop instead of ;,

Sorry, that comes of my little compiler hack, as you can see here: http://forum.dlang.org/thread/rbltrlxsogrfxjzqfpxe forum.dlang.org?page=3 and here, if you like to read my mother language ;) http://blog.rswhite.de/archives/791

If you want to play around with that, that's fine, but the language is not going to change, so please to post code which uses your changes. If you start making changes to the compiler, you can't really expect other people to help you figure out what's wrong with your code - especially since your changes could be causing your problems (though I think that that's unlikely in this particular case).
 but with that
 fixed I see
 
 Error: null dereference in function _Dmain
 q.d(103): Error: null dereference in function _Dmain
 
 which refers to
 
 test_not_null_foo(f1);
 
 which is a very weird error. test_not_null_foo takes a
 NotNull!Foo, not a Foo,
 and f1 is a Foo, and you haven't defined an implicit conversion
 from Foo to
 NotNull!Foo, so it should give an error about NotNull!Foo not
 being Foo.

I have, as you can see here: [code] property NotNull!(Foo) GetNN() { return this._nnf; } alias GetNN this; [/code] line 75 in my DPaste code.

Okay. I missed that, but that's probably your problem then. The definitions of of Foo and NotNull are recursive, which I don't believe is legal. It's almost certainly what's causing the compiler to eat up tons of CPU and memory and then die. In fact, if I fix the issue with Ptr returning a pointer to a class, and remove Foo's alias this and its associated function, the code compiles just fine with test_normal_foo(f2); uncommented. Which in and of itself is disturbing, since there's no implicit conversion anymore. So, I think that there's definitely a bug there beyond the weird error that you're seeing.
 If you compile without -O, this code compiles without error,
 which is wrong. And
 if you compile with -O, you get the weird null dereference
 error.

I like it, this error detect null referenced as i wanted, that great!

Best case, the compiler can catch really, really simple cases such as Foo foo; foo.func(); It will never do more than that, because anything beyond the simple case requires extensive flow analysis, and it's impossible to do detect it if it's a function parameter, global variable, or static variable, because that would require checking across functions (and potentially a _lot_ of functions with _very_ extensive flow analysis), which pretty much no language does. So, you're _never_ going to get full null detection. It's essentially impossible. At best, you'll get it to catch a few simple cases. However, the compiler doesn't even do that right now, so I don't know why you're getting the complaint about null dereferencing that you're getting.
 That's a bug i posted a while ago and i thougth that kenjii fix
 it in 2.060, or not?
 The compiler create an infinite loop and convert from Foo to
 NotNull!(Foo) and back and so on.
 If you create _one_ instance and returns them as pointer (or cast
 them as pointer, as you can se at my opCast method) the compiler
 breaks the conversion immediately. A little hack i detected and
 help me to realize the NotNull struct as i want. :)

Actually, it looks like it had been a few days since I updated my compiler. Now, if all I do is change Ptr to property auto Ptr() { static if (isPointer!(T) || is(T == class)) { return this._val; } else { return &this._val; } } then I get a segfault instead of dmd eating up CPU and memory, which is an improvement but not really acceptable, since the compiler isn't supposed to segfault. I don't know what the state of your bug report is, so I don't know if it's considered fixed or not. - Jonathan M Davis
Jul 02 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 If you want to play around with that, that's fine, but the 
 language is not
 going to change, so please to post code which uses your 
 changes. If you start
 making changes to the compiler, you can't really expect other 
 people to help
 you figure out what's wrong with your code - especially since 
 your changes
 could be causing your problems (though I think that that's 
 unlikely in this
 particular case).

Yes, sorry for that, it wasn't my intetion, i forgot (it was my own test case for that compiler change)
 Okay. I missed that, but that's probably your problem then. The 
 definitions of
 of Foo and NotNull are recursive, which I don't believe is 
 legal.

You mean it's illegal that i have two "alias this" in both, the Fo class and the NotNull struct? I hope that this case would be never illegal. And as i understood kenjii, he works on a fix that solves the problem with the infinity loop.
 It's almost certainly what's causing the compiler to eat up 
 tons of CPU and memory and
 then die. In fact, if I fix the issue with Ptr returning a 
 pointer to a class,
 and remove Foo's alias this and its associated function, the 
 code compiles
 just fine with

  test_normal_foo(f2);

 uncommented. Which in and of itself is disturbing, since 
 there's no implicit
 conversion anymore. So, I think that there's definitely a bug 
 there beyond the
 weird error that you're seeing.

But this was my intention: that Foo is implicit convertable to NotNull!(Foo) and that NotNull!(Foo) is implicit convertable to Foo.
 However, the compiler doesn't even do that right now, so I 
 don't know why
 you're getting the complaint about null dereferencing that 
 you're getting.

That's too bad.
 Actually, it looks like it had been a few days since I updated 
 my compiler.
 Now, if all I do is change Ptr to

   property
  auto Ptr() {
  static if (isPointer!(T) || is(T == class)) {
  return this._val;
  } else {
  return &this._val;
  }
  }

I get only a msg, that it doesn't compile. But this works fine: static if (is(T _unused : U*, U)) { property inout(T) Ptr() inout { return this._val; } } else { property inout(T*) Ptr() inout { return &this._val; } }
 then I get a segfault instead of dmd eating up CPU and memory, 
 which is an
 improvement but not really acceptable, since the compiler isn't 
 supposed to
 segfault. I don't know what the state of your bug report is, so 
 I don't know
 if it's considered fixed or not.

 - Jonathan M Davis

Here it is: http://forum.dlang.org/thread/bug-7980-3 http.d.puremagic.com%2Fissues%2F
Jul 02 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, July 02, 2012 12:45:16 Ali Çehreli wrote:
 On 07/02/2012 11:36 AM, Jonathan M Davis wrote:
 By the way, it's pointless to compile with both -w and -wi. -wi makes

it so
 that warnings are displayed without stopping compilation. -w makes it

so that
 warnings are displayed and treated as errors (so they stop

compilation). Pick
 one or the other. I don't know which the compiler picks if you give

it both,
 but it's going to have to pick one or the other, and it may not pick

the one
 that you want.

Then why is the documentation so misleading: -w enable warnings -wi enable informational warnings (i.e. compilation still proceeds normally) http://dlang.org/dmd-linux.html Me not know English good, but -wi sounds very much different from -w. :-T Further, both -w and -wi link to the following page, which does not mention -wi at all: http://dlang.org/warnings.html Sorry for whining... :(

That's what comes of -wi being tacked on later, I suppose. Clearly that needs to be fixed. If it were any other compiler -wi would be the default behavior, but Walter wrote it, so Nick had to beg until Walter suprisingly relented and added -wi. Personally, I just always compile with -w and that -w was the default, but whatever. The documentation needs to be fixed in either case. - Jonathan M Davis
Jul 02 2012
prev sibling parent "Namespace" <rswhite4 googlemail.com> writes:
At last a further Stack overflow, maybe you could explain me why.

It comes if i try to outsource the redundant code with a mixin 
template like this:

[code]
mixin template TRef(T : Object) {
private:
	NotNull!(T) _nn;

public:
	 property
	NotNull!(T) GetNN() {
		return this._nn;
	}

	alias GetNN this;
}

class Foo {
/*
private:
	NotNull!(Foo) _nnf;
*/
public:
	mixin TRef!(Foo);

	this() {
		this._nnf = NotNull!(Foo)(this);
	}

	void Identicate() const {
		writeln(Foo.stringof);
	}
/*
	 property
	NotNull!(Foo) GetNN() {
		return this._nnf;
	}

	alias GetNN this;
*/
}
[/code]

Without the mixin it compiles fine.
I tried comment out "alias this" in the mixin template and write 
it into the class, but it seems that it isn't relevant.
Jul 02 2012