1

I am not new to C++ but I was very surprised that this works:

struct Dummy {
    int foo() {
        return 1;
    }
};

int main(int argc, char** argv) {

    Dummy* d = nullptr;
    int ret = d->foo();
    //ret = 1

    return 0;
}

I understand that foo is per-class and not per-instance but is this a language feature people actually use ? Is there a benefit not having foo as static here ?

PinkTurtle
  • 6,942
  • 3
  • 25
  • 44
  • 1
    You dereference a null pointer, that leads to [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). Just don't do it. – Some programmer dude Mar 02 '20 at 07:58
  • Im satisfied with knowing this is not a language feature but undefined behavior. Thanks. I would rather have a compiler error at this point tho. – PinkTurtle Mar 02 '20 at 07:59
  • If you make it static then it becomes global to all instances of that type and you loose the ability to reference specific members of the instance. – SPlatten Mar 02 '20 at 08:03
  • The compiler is not required to emit a diagnostic in this situation. In this simple situation, a static analysis could detect the undefined behavior. But in even a slightly more complex scenario, it would be impossible to detect at compile time. If it is any consolation, my executable does `PinkTurtle.cpp:10:18: runtime error: member call on null pointer of type 'Dummy'` – Eljay Mar 02 '20 at 13:04
  • @Eljay I think I misspoke what I had in mind - I meant a runtime error actually (Im completely fine with this code *compiling*). Because as far as I remember dereferencing a null pointer would always give me a nullptr exception (tried to access memory location 0x000.......) but this time the code ran fine and it kinda shocked me. I have no idea why I did not get an exception this time? – PinkTurtle Mar 03 '20 at 19:02
  • Dereferencing a nullptr is undefined behavior. Some platforms may crash with a segmentation violation, some may merrily run with a broken axle and appear to work, some may terminate prematurely (like mine does). Or a mix of the above. – Eljay Mar 03 '20 at 20:17
  • You can Validate the pointer manually, `template T* V(T* p) { if (p) return p; throw "Oopsies"; }` and change `int ret = d->foo();` to `int ret = V(d)->foo();` – Eljay Mar 03 '20 at 20:22

0 Answers0