私はこれに偶然出くわしました、そして私は少し戸惑っています。
.NET 4.0を対象とした、すべてのデフォルト設定を備えた、すぐに使用できるVS 2010 F#プロジェクトがあります。
F#コードは次のようになります。
let test(a:int, b:int, c:int) = min a (min b c)
リリース用にコンパイルすると、生成されたILには奇妙なNOP
命令が散らばっています。このような:
このために生成されたIL(すべてのデフォルト設定を使用):
.method public static int32 test(int32 a,
int32 b,
int32 c) cil managed
{
// Code size 20 (0x14)
.maxstack 4
.locals init ([0] int32 V_0)
// HERE
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: bge.s IL_0009
IL_0005: ldarg.1
// HERE
IL_0006: nop
IL_0007: br.s IL_000b
IL_0009: ldarg.2
// HERE
IL_000a: nop
IL_000b: stloc.0
IL_000c: ldarg.0
IL_000d: ldloc.0
IL_000e: bge.s IL_0012
IL_0010: ldarg.0
IL_0011: ret
IL_0012: ldloc.0
IL_0013: ret
} // end of method Module1::test
私の.fsproj
プロジェクト構成は次のとおりです。
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<Tailcalls>true</Tailcalls>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<DocumentationFile>bin\Release\TestFsIL.XML</DocumentationFile>
</PropertyGroup>
ここで、行をコメントアウトする<DebugType>pdbonly</DebugType>
と、NOP
指示が消えます。しかしもちろん、PDBファイルもそうです!
.method public static int32 test(int32 a,
int32 b,
int32 c) cil managed
{
// Code size 17 (0x11)
.maxstack 4
.locals init (int32 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: bge.s IL_0007
IL_0004: ldarg.1
IL_0005: br.s IL_0008
IL_0007: ldarg.2
IL_0008: stloc.0
IL_0009: ldarg.0
IL_000a: ldloc.0
IL_000b: bge.s IL_000f
IL_000d: ldarg.0
IL_000e: ret
IL_000f: ldloc.0
IL_0010: ret
} // end of method Module1::test
行には微妙な違いもあります.locals
:
.locals init ([0] int32 V_0)
vs
.locals init (int32 V_0)
C#コンパイラを試したところNOP
、デバッグビルドでのみ命令が生成されますが、を使用してPDBファイルが含まれている場合でも、リリースビルドでは命令が生成されないようです<DebugType>pdbonly</DebugType>
。
質問:
C#でこれを回避できると思われるのに、PDBファイルが含まれている場合にリリースビルドのF#でNOP命令が生成されるのはなぜですか。
それらのNOPを取り除く方法はありますが、それでもPDBファイルはありますか?
PS。ここ とここにSOに関する関連する質問がありますが、そこにあるすべての回答は
デバッグモードでコンパイルしている場合、リリースモードでコンパイルすると
NOP
、
これは、示されているF#コンパイラでの私の経験と矛盾します。