Hacker News new | past | comments | ask | show | jobs | submit login

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:

  % g++-4.9 -Wall -O3 -std=c++11 test.cpp -o test; ./test
  0
  21

  % clang++ -Wall -O3 -std=c++11 test.cpp -o test; ./test 
  0
  21

  0x400886 <main()>    push   %rbp
  0x400887 <main()+1>  mov    %rsp,%rbp                          
  0x40088a <main()+4>  mov    $0xb,%edx
  0x40088f <main()+9>  mov    $0xa,%esi
  0x400894 <main()+14> mov    $0x0,%edi
  0x400899 <main()+19> callq  0x400910 <myclass::sum(int, int)>
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.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: