[CIQBUG] .equals(null) fails

The following snippet fails unexpectedly:

var v = "hello";
Sys.println("v="+v);
Sys.println("v has equals="+(v has :equals));
Sys.println("v.equals(hello)="+(v.equals("hello")));
Sys.println("v.equals(world)="+(v.equals("world")));
Sys.println("v.equals(null)="+(v.equals(null)));


Output:

v=hello
v has equals=true
v.equals(hello)=true
v.equals(world)=false
Failed invoking <symbol>
Unexpected Type Error
in onStart (.../TestEqualsApp.mc:14)


I would have expected the last statement to return false.
  • Since MonkeyC is its own language, I think it is up to the implementers to decide. I know that the code would be legal in Java, and similar code would be legal in Python. I'm not sure about Ruby though. Definitely not legal in C/C++.
  • The last line would work if was "v=null", as .equal() is for comparing strings, and not a string to a non string. Thus the unexpected type... You are passing a null object, and not the string "null";

    Now how do people post these code snippets and results in such a nice format! I just cut and past. :)
  • Given the definition of Object.equals(): "Test if this instance is equal to another instance of an object by using equals()." one can argue that with null, you don't have another object and thus the result is undefined.

    But according to the principle of least astonishment, I think it is safe to say that the result should definitely not fail with an internal error and also be well-defined. But that just might be me :-)
  • I'll argue both sides of the fence here. The docs for String say Returns: (Boolean) &#8212; true if the objects are equal, false otherwise. It does not mention throwing of the symbol not found exception, so at the very least we're talking about insufficient docs or undefined behavior.

    As for the principle of least astonishment issue, I thought I covered that in my response above. If you come from Java, you will definitely think this is a bug (you'd be astonished that it failed). If you come from a C/C++ background, you'd be astonished if it didn't.

    Travis
  • Actually Travis, with REAL C, it wouldn't have even compiled, as K+R "The C Programming Language" has no concept of objects or the grammar for them. Please don't use "C/C++" in the same sentence. Or have you never written code in acutal "C"? :)

    I used to have fun interviewing people that claimed to know "C" and have them write a program that simply displayed "Hello World!", without using anything from C++. Some gave up after 20 minutes... Others, we had to kick out after 45... :o It's one line of code if you don't include the function declaration itself!
  • int puts(const char*);

    int main() {
    return puts("Hello World!"), 0;
    }


    Yes. I've written plenty of C code in my days. I had actually posted the C code equivalent to the above when I wrote it originally, but didn't want to bore everyone with it and the call to strcmp that would be necessary to compare strings in C.

    const char v[] = "hello";
    printf("v=%s\n", v);
    printf("strcmp(v, \"hello\")=%d", strcmp(v, "hello"));
    printf("strcmp(v, \"world\")=%d", strcmp(v, "world"));
    printf("strcmp(v, NULL)=%d", strcmp(v, NULL)); // undefined behavior


    That code, while being C, would still compile with a C++ compiler, thus making it C/C++. The C++ variant that would be illegal would be ...

    std::string v("hello");
    std::cout << "v=" << v << std::endl;

    // you could also use compare here
    std::cout << "v == \"hello\"=" << (v == "hello") << std::endl;
    std::cout << "v == \"world\"=" << (v == "world") << std::endl;
    std::cout << "v == NULL=" << (v == NULL) << std::endl; // undefined behavior


    That is obviously C++ only.

    Travis
  • I'll file this as a bug so we can make sure this is expected behavior and define it if it not. Either way, it needs to be documented. :) Thanks for the find!
  • I just found out that we had already identified this while fixing another issue, so this bug will be fixed in the next release.
  • I just found out that we had already identified this while fixing another issue, so this bug will be fixed in the next release.


    +1

    Highly appreciated!