Holy cow, I wrote a book!
When you debug through some managed code at the assembly level,
you'll find a whole lot of seemingly pointless instructions
that perform a comparison but ignore the result.
What's the point of comparing two values if you don't care what
the result is?
In C++, invoking an instance method on a
NULL pointer results in undefined behavior.
In other words, if you do it,
the compiler is allowed to do anything it wants.
And what most compilers do is, um, nothing.
They don't take any special steps if the this pointer is
they just generate code on the assumption that it isn't.
In practice, this often means that everything seems to run just
fine until you access a member variables or call a virtual functions,
and then you crash.
The C# language, by comparison,
quite explicit about what
happens if you invoke an instance method on a null object
The value of E is checked to be valid.
If the value of E is null,
is thrown and no further steps are executed.
The null reference exception must be thrown before the method can
That's what the strange cmp [ecx], ecx comparison is for.¹
The compiler doesn't actually care what the result of the comparison is;
it just wants to raise an exception if ecx is null.
If ecx is null, the attempt to dereference it (in order
to perform the comparison) will raise an access violation, which the
runtime inspects and turns into a NullReferenceException.
cmp [ecx], ecx
The test is usually against the ecx register since the CLR
happens to use²
the fastcall calling convention,
which for instance methods passes the this pointer in the
The pointer the compiler wants to test is going to wind up in the
ecx register sooner or
so it's not surprising that the test, when it happens,
is made against the ecx register.
¹Although this statement is written as if it were a fact,
it is actually my interpretation based on observation and
thinking about how language features are implemented.
not an official position
of the CLR team
nor Microsoft Corporation,
and that interpretation may ultimately prove incorrect.
²"Happens to use"
means that this is an implementation detail,
not a contractual guarantee.¹
³Unless the call is optimized.
For example, the function might be inlined.