Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String constants embedded twice in .Net?

Tags:

c#

.net

Say I have a simple (the simplest?) C# program:

class Program {
    static void Main() {
      System.Console.WriteLine("Hello, world");
    }
}

If, I compile that code and look at the resultant .exe, I see the "Hello, world" string in the exe image as expected.

If I refactor the code to:

class Program {
    const string Greeting = "Hello, world";
    static void Main() {
      System.Console.WriteLine(Greeting);
    }
}

If I compile that code and look at the resultant .exe, I see the "Hello, world" string literal in the exe image twice. This was surprising to me. I was under the impression that string literals were shared, and that it would therefor only show up in the image one time. Can anyone explain this? Perhaps this second copy of the string is needed for reflection metadata?

like image 299
MarkPflug Avatar asked Dec 05 '14 22:12

MarkPflug


1 Answers

The ECMA-335 CLI specification sheds some light on this. A C# const is declared as a static literal field in IL. From section I.8.6.1.2 (emphasis mine):

The literal constraint promises that the value of the location is actually a fixed value of a built-in type. The value is specified as part of the constraint. Compilers are required to replace all references to the location with its value, and the VES therefore need not allocate space for the location. This constraint, while logically applicable to any location, shall only be placed on static fields of compound types. Fields that are so marked are not permitted to be referenced from CIL (they shall be in-lined to their constant value at compile time), but are available using reflection and tools that directly deal with the metadata.

Thus the compiler takes the constant value and replaces it throughout the code. It is not allowed to reference the constant storage. What it does from there, is what it does for any other literal string. It gives it a slot in the metadata table and uses the ldstr op code to load the string. Thus, the value appears twice in your assembly. Once in the storage location for the constant, which cannot be referenced by a compliant compiler. And another time in your metadata table.

like image 194
Mike Zboray Avatar answered Nov 07 '22 09:11

Mike Zboray