The optimizer decides that all remaining actions do not affect and optimize it. Right or wrong is another matter.
In particular:
X x;
creates an empty x
cout << x;
calls:
return (os << obj);
; "os" ( ), , .
cout << "hehe"; // comment this and infinite loop is gone
, .
, x - , cout << "hehe";, , .