The problem with undefined behavior, is that the compiler is allowed to assume that it will not happen.
First, within myclass::sum, the compiler can assume that "this" will never be null. In your example, you pass "this" to cout; if the iostream code is inlined, and it has a conditional on the passed pointer, for instance to special-case the output of a null pointer, the compiler will omit the comparison and output only the code for the non-null case.
Second, within the main function. The compiler can see you are calling a method with a null "this" pointer. Since this is undefined behavior, it clearly can't happen, and there must be something earlier in the call path that leads to that part of the code never being executed. Therefore, since this is the first thing in the main function, the compiler can assume that main() will never be called, and replace it with an empty function (to satisfy the linker).
If your compiler doesn't do that, it only means that it's not smart enough yet. The behavior can change in later versions of your compiler, or if you use a different compiler.
I didn't understand why my point was downvoted, anybody who likes to know how things work on backstage or likes to hack stuff would find it interesting.
Sure, undefined behavior can assume anything, but the compiler writer still has to respect the ABI, right?
I was reading the Itanium C++ ABI draft and the only thing I found about it is:
"If a class has a non-virtual destructor, and a deleting destructor is emitted for that class, the deleting destructor must correctly handle the case that the this pointer is NULL. All other destructors, including deleting destructors for classes with a virtual destructor, may assume that the this pointer is not NULL."
https://mentorembedded.github.io/cxx-abi/abi.html
However, you can see that I don't have an instance, there is no object so the destructor won't be called. It means that the compiler writer won't probably consider checking 'this' pointer for null - clang/gcc both don't care:
The 'this' pointer is just a parameter in the register EDI.
NOTE: I don't recommend anyone writing code like this. I'm always concerned about UB and I agree with you. But it's still interesting to know how things really are.
First, within myclass::sum, the compiler can assume that "this" will never be null. In your example, you pass "this" to cout; if the iostream code is inlined, and it has a conditional on the passed pointer, for instance to special-case the output of a null pointer, the compiler will omit the comparison and output only the code for the non-null case.
Second, within the main function. The compiler can see you are calling a method with a null "this" pointer. Since this is undefined behavior, it clearly can't happen, and there must be something earlier in the call path that leads to that part of the code never being executed. Therefore, since this is the first thing in the main function, the compiler can assume that main() will never be called, and replace it with an empty function (to satisfy the linker).
If your compiler doesn't do that, it only means that it's not smart enough yet. The behavior can change in later versions of your compiler, or if you use a different compiler.