This confuses me a lot.
My understanding is that when I compile an application it becomes optimized code that my operating system reads. Things from my source code such as variable names, line numbers, etc., no longer have meaning.
So then how am I able to build-and-run code like
try
{
// ...
}
catch ( Exception E )
{
Console.WriteLine("Exception occured: {0}", E.StackTrace);
}
and get all this detailed information about what part of my source code is respomsible for an exception.
Now, I understand that in .NET my C# code doesn't intially become low-level "operating system code" but rather Microsoft Intermediary Language. What I'm guessing it that MIL, in order to generate this exception info, perserves some type of mapping between my source code and the compiled code. This seems like a huge waste, isn't it? So "compiling" in .NET isn't really translating source code to machine code; it is creating machine code in addition to source code. That means that all the applications on my Windows machine have metadata pertraining to their source code.
Or am I completely wrong about all this?