简体   繁体   中英

C# Preprocessor Directives in the IL code

I try to use simple preprocessor directives for debug and release mode in C#.

For example:

using System;
public class C {
    public void M() {
        #if DEBUG
            Console.WriteLine("Debug");
        #else
            Console.WriteLine("Release");
        #endif
    }
}

This code very simple and clear.

But when I see into IL code I don't have anything about debug directive.

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit C
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig 
        instance void M () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 13 (0xd)
        .maxstack 8

        IL_0000: nop
        IL_0001: ldstr "Release"
        IL_0006: call void [mscorlib]System.Console::WriteLine(string)
        IL_000b: nop
        IL_000c: ret
    } // end of method C::M

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x205e
        // Code size 8 (0x8)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: nop
        IL_0007: ret
    } // end of method C::.ctor

} // end of class C

It's very interesting to me, why it happens.

I mean why I don't see anything about DEBUG mode in IL code?

PS I use sharplab for see the IL code.

PS2 live example

It is because the preprocessor directives are used by the compiler to generate different IL code based on configuration. It is not used by the CLR.

As for why SharpLab isn't doing the right thing, it uses Rosyln and only sets the optimization settings. It doesn't set the preprocessor variable.

public void SetOptimize([NotNull] IWorkSession session, [NotNull] string optimize) {
    var project = session.Roslyn.Project;
    var options = ((CSharpCompilationOptions)project.CompilationOptions);
    session.Roslyn.Project = project.WithCompilationOptions(
        options.WithOptimizationLevel(optimize == Optimize.Debug ? OptimizationLevel.Debug : OptimizationLevel.Release)
    );
}

I suggest you open an issue with SharpLab that they implement this to work as expected.

There are two concepts that seem to be confusing you.

  1. Release/Debug compilation mode:

    This controls whether the compiler emits debug info into the code (eg NOP instructions for setting breakpoints) and some other aspects such as optimizations carried out on both compiler and JIT level. This is based on /debug parameter to C# compiler.

  2. Preprocessor symbols:

    This controls what symbols are defined for the compilation run. By default, these are set to DEBUG and TRACE in Debug mode and TRACE in Release mode when using Visual Studio to create the C# project. These symbols are then used to resolve #if directives that you're using. This is based on /define parameter to C# compiler

What seems to be happening in your case is that your tool tells the C# compiler to run in Debug/Release mode but doesn't supply the expected preprocessor symbol ( DEBUG ) in the parameters. Therefore you see the non- DEBUG code in both Release and Debug configurations.

See also: Microsoft docs: C# compiler options by category

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM