digitalmars.D.learn - Acces Violation: assert with null instance
- Lionello Lunesu (10/10) Jan 04 2007 I really think this used to work (like in C++) :
- Lionello Lunesu (7/8) Jan 05 2007 ..Guess not. I've just tested with some old versions, as old as 0.119,
- Lionello Lunesu (6/7) Jan 05 2007 For the record:
-
Stewart Gordon
(8/18)
Jan 10 2007
- Frits van Bommel (10/15) Jan 10 2007 As I commented recently when this bug was added to bugzilla, it's in the...
- Stewart Gordon (9/26) Jan 10 2007 "The invariant can be checked when a class object is the argument to an
- Lionello Lunesu (4/32) Jan 10 2007 I agree, that why I filed that bug :)
- Frits van Bommel (3/10) Jan 11 2007 Huh. I must've read that wrong. I thought it said "is checked". I guess
- Walter Bright (3/23) Jan 24 2007 It does check if it's null. That's how the access violation exception
- Sean Kelly (4/28) Jan 24 2007 But that's generated by the hardware, isn't it? Shouldn't assert
- Walter Bright (3/10) Jan 25 2007 Why, if the hardware does it for you (without extra bloat)?
- Frank Benoit (keinfarbton) (2/3) Jan 26 2007 Is it possible to catch a segmentation fault and convert it into a
- Sean Kelly (7/20) Jan 26 2007 Just so a file and line number are available. Though someone mentioned
- Frits van Bommel (9/29) Jan 26 2007 Yes, an assert(o !is null) is performed. But it's performed *inside*
- Sean Kelly (7/38) Jan 26 2007 I think the problem is more that Phobos only ships with a release build
- Frits van Bommel (2/18) Jan 26 2007 Separate libraries is also an option, of course ;).
- Frits van Bommel (11/33) Jan 24 2007 Access violations are hardware-generated, and not a particularly nice
- Walter Bright (4/10) Jan 25 2007 If you run it under the debugger, it should pop up with the cursor on
- Bradley Smith (22/46) Jan 24 2007 Perhaps this is a better example.
- Walter Bright (3/4) Jan 26 2007 You can catch access errors by catching Exception, at least under
- Bradley Smith (15/17) Jan 26 2007 I know. That is not the point. The point is that evaluation of a null
- Frank Benoit (keinfarbton) (7/9) Jan 26 2007 I think it is more like
- Sean Kelly (5/10) Jan 26 2007 With Unix you have to set up a signal handler for SIGSEGV. However, I'm...
I really think this used to work (like in C++) : #class Class {} #void main(){ With 1.0, I get an access violation in _D9invariant12_d_invariantFC6ObjectZv, but why? I have to rewrite it as assert(c !is null), but I don't recall having to do this before.... L.
Jan 04 2007
Lionello Lunesu wrote:I really think this used to work (like in C++) :..Guess not. I've just tested with some old versions, as old as 0.119, and I still got the Access Violation. Odd. Shouldn't it work though? Class c = null; assert(c); L.
Jan 05 2007
Lionello Lunesu wrote:_D9invariant12_d_invariantFC6ObjectZvFor the record: When linking against a debug build of Phobos (-unittest -g -w), I get: Error: AssertError Failure internal\invariant.d(14) Posted on bugzilla as Issue 796. L.
Jan 05 2007
Lionello Lunesu wrote:I really think this used to work (like in C++) : #class Class {} #void main(){ With 1.0, I get an access violation in _D9invariant12_d_invariantFC6ObjectZv, but why?<snip> For some strange reason, assert on an object reference checks that the invariants are satisfied instead of that the reference isn't null. There's nothing to this effect in the spec, so I don't know how it came about. While it may be useful, it certainly shouldn't do it _instead of_ checking it isn't null. Stewart.
Jan 10 2007
Stewart Gordon wrote:For some strange reason, assert on an object reference checks that the invariants are satisfied instead of that the reference isn't null. There's nothing to this effect in the spec, so I don't know how it came about. While it may be useful, it certainly shouldn't do it _instead of_ checking it isn't null.As I commented recently when this bug was added to bugzilla, it's in the spec. It's just not where you'd expect it. It's noted at http://www.digitalmars.com/d/class.html#invariants (the section on class invariants) instead of in the section on asserts. I've since added a warning about this on the comments page for the page containing the section on asserts. Also, the null check *is* in the code, but when Phobos is compiled in release mode (which the pre-compiled version is) the assert isn't performed...
Jan 10 2007
Frits van Bommel wrote:Stewart Gordon wrote:What is the Bugzilla issue number? I can't seem to find it.For some strange reason, assert on an object reference checks that the invariants are satisfied instead of that the reference isn't null. There's nothing to this effect in the spec, so I don't know how it came about. While it may be useful, it certainly shouldn't do it _instead of_ checking it isn't null.As I commented recently when this bug was added to bugzilla, it's in the spec. It's just not where you'd expect it.It's noted at http://www.digitalmars.com/d/class.html#invariants (the section on class invariants) instead of in the section on asserts. I've since added a warning about this on the comments page for the page containing the section on asserts. Also, the null check *is* in the code, but when Phobos is compiled in release mode (which the pre-compiled version is) the assert isn't performed..."The invariant can be checked when a class object is the argument to an assert() expression, as:" I see this as giving an _additional_ use of assert, something that assert on a class object may do as an extra. The general contract of assert is supposed to remain, and the fact that out of the box it doesn't certainly constitutes a bug, at least IMO. Stewart.
Jan 10 2007
Stewart Gordon wrote:Frits van Bommel wrote:796Stewart Gordon wrote:What is the Bugzilla issue number? I can't seem to find it.For some strange reason, assert on an object reference checks that the invariants are satisfied instead of that the reference isn't null. There's nothing to this effect in the spec, so I don't know how it came about. While it may be useful, it certainly shouldn't do it _instead of_ checking it isn't null.As I commented recently when this bug was added to bugzilla, it's in the spec. It's just not where you'd expect it.I agree, that why I filed that bug :) L.It's noted at http://www.digitalmars.com/d/class.html#invariants (the section on class invariants) instead of in the section on asserts. I've since added a warning about this on the comments page for the page containing the section on asserts. Also, the null check *is* in the code, but when Phobos is compiled in release mode (which the pre-compiled version is) the assert isn't performed..."The invariant can be checked when a class object is the argument to an assert() expression, as:" I see this as giving an _additional_ use of assert, something that assert on a class object may do as an extra. The general contract of assert is supposed to remain, and the fact that out of the box it doesn't certainly constitutes a bug, at least IMO.
Jan 10 2007
Stewart Gordon wrote:"The invariant can be checked when a class object is the argument to an assert() expression, as:" I see this as giving an _additional_ use of assert, something that assert on a class object may do as an extra. The general contract of assert is supposed to remain, and the fact that out of the box it doesn't certainly constitutes a bug, at least IMO.Huh. I must've read that wrong. I thought it said "is checked". I guess this one makes more sense. That definitely makes it a bug.
Jan 11 2007
Stewart Gordon wrote:Lionello Lunesu wrote:It does check if it's null. That's how the access violation exception gets thrown.I really think this used to work (like in C++) : #class Class {} #void main(){ With 1.0, I get an access violation in _D9invariant12_d_invariantFC6ObjectZv, but why?<snip> For some strange reason, assert on an object reference checks that the invariants are satisfied instead of that the reference isn't null. There's nothing to this effect in the spec, so I don't know how it came about. While it may be useful, it certainly shouldn't do it _instead of_ checking it isn't null. Stewart.
Jan 24 2007
Walter Bright wrote:Stewart Gordon wrote:But that's generated by the hardware, isn't it? Shouldn't assert explicitly check whether c is null before calling its invariant? SeanLionello Lunesu wrote:It does check if it's null. That's how the access violation exception gets thrown.I really think this used to work (like in C++) : #class Class {} #void main(){ With 1.0, I get an access violation in _D9invariant12_d_invariantFC6ObjectZv, but why?<snip> For some strange reason, assert on an object reference checks that the invariants are satisfied instead of that the reference isn't null. There's nothing to this effect in the spec, so I don't know how it came about. While it may be useful, it certainly shouldn't do it _instead of_ checking it isn't null. Stewart.
Jan 24 2007
Sean Kelly wrote:Walter Bright wrote:Yes.It does check if it's null. That's how the access violation exception gets thrown.But that's generated by the hardware, isn't it?Shouldn't assert explicitly check whether c is null before calling its invariant?Why, if the hardware does it for you (without extra bloat)?
Jan 25 2007
Why, if the hardware does it for you (without extra bloat)?Is it possible to catch a segmentation fault and convert it into a InvalidPointerException and continue?
Jan 26 2007
Walter Bright wrote:Sean Kelly wrote:Just so a file and line number are available. Though someone mentioned the code already does something like "assert(obj); obj.invariant();" and the problem here was that it was a release build? If this is the case I'm fine with the current behavior. I really only care about this sort of thing if asserts are enabled. SeanWalter Bright wrote:Yes.It does check if it's null. That's how the access violation exception gets thrown.But that's generated by the hardware, isn't it?Shouldn't assert explicitly check whether c is null before calling its invariant?Why, if the hardware does it for you (without extra bloat)?
Jan 26 2007
Sean Kelly wrote:Walter Bright wrote:Yes, an assert(o !is null) is performed. But it's performed *inside* _d_invariant, which is part of Phobos. And since Phobos is only distributed as a release build, that means the assert is off by default _even if *your* program has asserts enabled_. You need to recompile Phobos to change this behavior. This is bad. Perhaps that assert should just be converted to an "if (!o) _d_assert(__FILE__, __LINE__)" since _d_invariant will (presumably) only be called if the application has assertions enabled?Sean Kelly wrote:Just so a file and line number are available. Though someone mentioned the code already does something like "assert(obj); obj.invariant();" and the problem here was that it was a release build? If this is the case I'm fine with the current behavior. I really only care about this sort of thing if asserts are enabled.Walter Bright wrote:Yes.It does check if it's null. That's how the access violation exception gets thrown.But that's generated by the hardware, isn't it?Shouldn't assert explicitly check whether c is null before calling its invariant?Why, if the hardware does it for you (without extra bloat)?
Jan 26 2007
Frits van Bommel wrote:Sean Kelly wrote:I think the problem is more that Phobos only ships with a release build rather than that the code is broken. What should probably be the case is that DMD should link phobos.lib if -release is set and link phobosd.lib otherwise. Specifying both -debug and -release... well, I'm not sure what that does so I can't say :-) SeanWalter Bright wrote:Yes, an assert(o !is null) is performed. But it's performed *inside* _d_invariant, which is part of Phobos. And since Phobos is only distributed as a release build, that means the assert is off by default _even if *your* program has asserts enabled_. You need to recompile Phobos to change this behavior. This is bad. Perhaps that assert should just be converted to an "if (!o) _d_assert(__FILE__, __LINE__)" since _d_invariant will (presumably) only be called if the application has assertions enabled?Sean Kelly wrote:Just so a file and line number are available. Though someone mentioned the code already does something like "assert(obj); obj.invariant();" and the problem here was that it was a release build? If this is the case I'm fine with the current behavior. I really only care about this sort of thing if asserts are enabled.Walter Bright wrote:Yes.It does check if it's null. That's how the access violation exception gets thrown.But that's generated by the hardware, isn't it?Shouldn't assert explicitly check whether c is null before calling its invariant?Why, if the hardware does it for you (without extra bloat)?
Jan 26 2007
Sean Kelly wrote:Frits van Bommel wrote:Separate libraries is also an option, of course ;).Yes, an assert(o !is null) is performed. But it's performed *inside* _d_invariant, which is part of Phobos. And since Phobos is only distributed as a release build, that means the assert is off by default _even if *your* program has asserts enabled_. You need to recompile Phobos to change this behavior. This is bad. Perhaps that assert should just be converted to an "if (!o) _d_assert(__FILE__, __LINE__)" since _d_invariant will (presumably) only be called if the application has assertions enabled?I think the problem is more that Phobos only ships with a release build rather than that the code is broken. What should probably be the case is that DMD should link phobos.lib if -release is set and link phobosd.lib otherwise. Specifying both -debug and -release... well, I'm not sure what that does so I can't say :-)
Jan 26 2007
Walter Bright wrote:Stewart Gordon wrote:Access violations are hardware-generated, and not a particularly nice way to detect an error. Especially since no usable file & line information is generated. The invariant checking code also contains "assert(o !is null)" before it does anything else, but that code is in Phobos. And the Phobos libs distributed with DMD seem to be compiled with '-release', stripping that code. And even if it wasn't, the file & line displayed on failure would be Phobos' internal/invariant.d:14 or similar instead of the place the user put an assert(obj).Lionello Lunesu wrote:It does check if it's null. That's how the access violation exception gets thrown.I really think this used to work (like in C++) : #class Class {} #void main(){ With 1.0, I get an access violation in _D9invariant12_d_invariantFC6ObjectZv, but why?<snip> For some strange reason, assert on an object reference checks that the invariants are satisfied instead of that the reference isn't null. There's nothing to this effect in the spec, so I don't know how it came about. While it may be useful, it certainly shouldn't do it _instead of_ checking it isn't null.
Jan 24 2007
Frits van Bommel wrote:Walter Bright wrote:If you run it under the debugger, it should pop up with the cursor on where it faulted (line and file). If it doesn't, it's a bug in the debugger or the debug output of the compiler.It does check if it's null. That's how the access violation exception gets thrown.Access violations are hardware-generated, and not a particularly nice way to detect an error. Especially since no usable file & line information is generated.
Jan 25 2007
Walter Bright wrote:Stewart Gordon wrote:Perhaps this is a better example. import std.stdio; import std.asserterror; class Class {} void main() { Class c; try { version (alt) { assert(false); } assert(c); } catch (AssertError e) { writefln("An assert failed: ", e); } } C:\>dmd assertNull.d c:\dmd\bin\..\..\dm\bin\link.exe assertNull,,,user32+kernel32/noi; C:\>assertNull Error: Access Violation C:\>dmd assertNull.d -version=alt c:\dmd\bin\..\..\dm\bin\link.exe assertNull,,,user32+kernel32/noi; C:\>assertNull An assert failed: AssertError Failure assertNull(7)Lionello Lunesu wrote:It does check if it's null. That's how the access violation exception gets thrown.I really think this used to work (like in C++) : #class Class {} #void main(){ With 1.0, I get an access violation in _D9invariant12_d_invariantFC6ObjectZv, but why?<snip> For some strange reason, assert on an object reference checks that the invariants are satisfied instead of that the reference isn't null. There's nothing to this effect in the spec, so I don't know how it came about. While it may be useful, it certainly shouldn't do it _instead of_ checking it isn't null. Stewart.
Jan 24 2007
Bradley Smith wrote:} catch (AssertError e) {You can catch access errors by catching Exception, at least under Windows, because I haven't figured out how to do it under Linux.
Jan 26 2007
Walter Bright wrote:You can catch access errors by catching Exception, at least under Windows, because I haven't figured out how to do it under Linux.I know. That is not the point. The point is that evaluation of a null reference is inconsistent. For an if statement, null is evaluated as false, but for an assert it is an access violation. See code below. Conceptually, assert (expression) is nothing more that "if (!expression) throw new AssertError;". However, it doesn't act that way. import std.stdio; class Class {} void main() { Class c; if (!c) { writefln("c is false?"); } assert(c); }
Jan 26 2007
Conceptually, assert (expression) is nothing more that "if (!expression) throw new AssertError;". However, it doesn't act that way.I think it is more like if ( expression != 0 ) throw new AssertError; that means .opEquals is called probably on a null reference, and so the segfault is caused. Hm... Or is that what '!' does?
Jan 26 2007
Walter Bright wrote:Bradley Smith wrote:With Unix you have to set up a signal handler for SIGSEGV. However, I'm not entirely sure whether exceptions can be thrown from within signal handlers. If anyone knows I'd love to hear the answer. Sean} catch (AssertError e) {You can catch access errors by catching Exception, at least under Windows, because I haven't figured out how to do it under Linux.
Jan 26 2007