Question

Considérez cet extrait C #:

static string input = null;
static string output = null;

static void Main(string[] args)
{
     input = "input";
     output = CallMe(input);
}

public static string CallMe(string input)
{
     output = "output";
     return output;
}

Dissassembling en utilisant des spectacles de réflecteur:

.method private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
        .maxstack 8
        L_0000: nop 
        L_0001: ldstr "input"
        L_0006: stsfld string Reflector_Test.Program::input
        L_000b: ldsfld string Reflector_Test.Program::input
        L_0010: call string Reflector_Test.Program::CallMe(string)
        L_0015: stsfld string Reflector_Test.Program::output
        L_001a: ret 
    }

 .method public hidebysig static string CallMe(string input) cil managed
    {
        .maxstack 1
        .locals init (
            [0] string CS$1$0000)
        L_0000: nop 
        L_0001: ldstr "output"
        L_0006: stsfld string Reflector_Test.Program::output
        L_000b: ldsfld string Reflector_Test.Program::output
        L_0010: stloc.0 
        L_0011: br.s L_0013
        L_0013: ldloc.0 
        L_0014: ret 
    }

La pièce qui me déconcerte est:

L_0010: stloc.0 
L_0011: br.s L_0013
L_0013: ldloc.0 

Il stocke l'élément, les branches à la ligne suivante (ce qui aurait été exécuté de toute façon) et charge à nouveau.

Y at-il une raison?

Était-ce utile?

La solution

Cela ne se produit que dans Debug, pas dans la version. Je soupçonne son pour aider pendant le débogage. Il vous permet peut-être de chuck des points d'arrêt et voir déclaration mi la valeur de retour.

Notez la version a beaucoup plus concise IL:

.method private hidebysig static void Main(string[] args) cil managed
{
    .maxstack 8
    L_0000: ldstr "input"
    L_0005: stsfld string Reflector_Test.Program::input
    L_000a: ldsfld string Reflector_Test.Program::input
    L_000f: call string Reflector_Test.Program::CallMe(string)
    L_0014: stsfld string Reflector_Test.Program::output
    L_0019: ret 
}




.method public hidebysig static string CallMe(string input) cil managed
{
    .maxstack 8
    L_0000: ldstr "output"
    L_0005: stsfld string Reflector_Test.Program::output
    L_000a: ldsfld string Reflector_Test.Program::output
    L_000f: ret 
}

Autres conseils

Je pense que ce code est pour l'exécution d'une boilerplate instruction de retour, le compilateur exécute un saut inconditionnel à la dernière ligne, et charge la valeur de retour dans un registre avant d'exécuter la ret. Le JIT optimisera mieux, je pense que le compilateur ne prend pas la peine de faire des OPTIMISATIONS.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top