About Monkey 2 › Forums › Monkey 2 Development › Bug: Null pointers aren't really null pointers?
Tagged: bug
This topic contains 10 replies, has 5 voices, and was last updated by 
 Samah 2 years, 10 months ago.
- 
		AuthorPosts
 - 
		
			
				
June 18, 2016 at 3:34 am #1133
Looks like you can successfully call a method on a null reference. It only fails if it tries to access Self, both explicitly or implicitly.
[/crayon]Monkey123456789101112[crayon-5cb9e34d4a056731101864 inline="true" ]Function Main:Void()Local a:Fooa.Hello()EndClass FooField bar:String = "asd"Method Hello()Print "lol"'Print barEndEndWorks fine, but will crash if you uncomment Print bar. You can do pretty much anything else.
I spent about an hour hunting down an uninitialised field in another class, because this bug told me it was initialised.
June 18, 2016 at 4:32 am #1135This is by design – Self can be Null for non-virtual methods.
June 18, 2016 at 4:50 am #1137Whether or not it’s by design, you should never be able to call a method on a non-existent object. This isn’t Objective-C where you can send a message to nil.
June 18, 2016 at 5:49 am #1140I can see that this’ll cause quite a few headaches in the future!
@Mark – can you show an example on how this is useful design?
June 18, 2016 at 8:18 am #1147I’ve used it a few times in c++, usually to prevent code from having to constantly check for null pointers in frequently called methods, eg: when incrementing/decrementing reference counts etc, eg:
Monkey1234567void retain(){if( this ) ++_refs;}void release(){if( this && !--_refs ) delete this; //doubly naughty!}This saves you the hassle of having to wrap ALL retain() calls in ‘if( blah ) blah->retain();’, eg: you can just use blah->retain(); (or blah->release() etc ) even if blah is null.
So I guess it’s useful for frequently used methods of classes that may have many null instances.
I can live without this if it’s causing people hassles, although it’s never caused me any problems in the past – the first field access will raise an exception anyway if the method tries to do anything with the instance.
June 18, 2016 at 11:40 am #1160Monkey1234Function Main:Void()Local a:Fooa.Hello()EndThe Variable is ‘clearly’ not initialized. The C# way of throwing a compile error because you try to call a method on a non initialized variable would be more reasonable to me.
June 18, 2016 at 12:01 pm #1162Sure, in that example it’s “clear”, but in my situation it was one of ten or so fields in a class, that was supposed to be assigned later in the app lifecycle. I was trying to access the field before it got to that stage. If it had thrown an actual exception on the method call, I would have been able to track it down sooner.
If code in a method is executing, I would expect that the object exists to actually call it.
Can’t you inline some of those checks anyway?
Could you make it some kind of pragma that only does runtime checks in debug mode?June 18, 2016 at 12:16 pm #1163Well, for local variables it should be a compile error but for fields this is indeed absolutely unexpected.
June 18, 2016 at 12:46 pm #1164this is nice only sometimes as pointed out. it would be nice to keep this behavior but only if it can be explicit. maybe something along the lines of the null conditional operator on the roadmap…
something like
[removed]
[edit]
Actually
a??.Hello()although in Marks code example the class itself is checking so using a null conditional would amount to less code being executable, correct? So the only use case is if we never check for null anywhere right? and if thats the case, what is the use case?
June 19, 2016 at 12:58 pm #1173Well, one could use the same approach like in many functional programming languages where null is not a valid state for a variable if not stated explicitly.
e.g.
Monkey123456789Local a:MyClass = null ' Compile Error because null is not allowedLocal b:MyClass Option = None' OK, Option type can have no valueLocal v:MyClass Option = Some(new MyClass())' the operation 'a' might return nothing (None)'( Or use Maybe<T> / Either<T> / Just<T> / Neither intead of option)If a = null then ... ' Error "a" cannot be nullThis has two major benefits: It is very easy to eliminate unnecessary null checks (because null is not allowed) and it is also very easy to distinguish between a result that is null and a failed operation that returns nothing because null <> None.
Here is one of the many article on this matter : *click*
June 19, 2016 at 2:25 pm #1175I guess I’ve been spoiled somewhat with Swift’s optionals recently. Adding something like that would be a huge undertaking, and I would expect it in version 2.0 at the earliest.
 - 
		AuthorPosts
 
You must be logged in to reply to this topic.