コンパイルの警告
このページでは、一般的なコンパイル時の警告とその修正方法について説明します。
IgnoreWarning 属性
Unity.Burst.CompilerServices.IgnoreWarningAttribute
属性を指定すると、Burst でコンパイルされる特定の関数についての警告を抑制できます。ただし、Burst コンパイラーで生成される警告は非常に重要なので、この属性は必要な場合にのみ慎重に使用するようにしてください。以下のセクションでは、警告を抑制してもよい具体的な状況について説明します。
BC1370
警告 BC1370 は以下のようなメッセージを生成します。
An exception was thrown from a function without the correct
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
guard...
(正しい[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
ガードなしで関数から例外がスローされました...)
この警告は、[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
で保護されていないコードにおいて例外がスローされると発生します。エディターではスローされた例外がキャッチされコンソールに記録されますが、プレイヤーのビルドでは throw
は強制終了となり、アプリケーションがクラッシュします。[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
属性で保護された関数はプレイヤービルドに含まれないため、Burst ではこれらの例外について警告が表示され、この属性で保護された関数内にコードを配置するよう推奨されます。ただし、意図的に例外をスローしてアプリケーションをクラッシュさせる場合は、IgnoreWarningAttribute
を使用することで、throw
に関する Burst の警告を抑制できます。
[IgnoreWarning(1370)]
int DoSomethingMaybe(int x)
{
if (x < 0) throw new Exception("Dang - sorry I crashed your game!");
return x * x;
}
Note
この警告は、プレイヤービルドに永続する例外に対してのみ生成されます。プレイヤービルドにコンパイルされないエディター専用またはデバッグ専用の例外スローには、この警告は生成されません。
BC1371
警告 BC1371 は以下のようなメッセージを生成します。
A call to the method 'xxx' has been discarded, due to its use as an argument to a discarded method... (メソッド 'xxx' の呼び出しは、破棄されたメソッドの引数として使用されるため、破棄されました...)
この警告を理解するために、以下の例を考えてみましょう。
[BurstDiscard]
static void DoSomeManagedStuff(int x)
{
///.. Burst コンパイルが無効なときのみ実行されます。
}
// マネージコードに渡す必要のある結果を計算する関数
int BurstCompiledCode(int x,int y)
{
return y+2*x;
}
[BurstCompile]
void BurstMethod()
{
var myValue = BurstCompiledCode(1,3);
DoSomeManagedStuff(myValue);
}
Unity のリリースモードで C# コードをコンパイルする際には、最適化によりローカル変数 myValue
が削除されます。そのため、Burst が受け取るコードは以下のようになります。
[BurstCompile]
void BurstedMethod()
{
DoSomeManagedStuff(BurstCompiledCode(1,3));
}
これにより、Burst では BurstCompiledCode
の引数とともに DoSomeManagedStuff
が破棄されるため、警告が生成されます。つまり、BurstCompiledCode
関数が実行されなくなるので、警告が生成されるのです。
このような動作を意図しないのであれば、変数には用途を複数持たせてください。以下に例を示します。
void IsUsed(ref int x)
{
// 削除を回避するためのダミー関数
}
[BurstCompile]
void BurstedMethod()
{
var myValue = BurstCompiledCode(1,3);
DoSomeManagedStuff(myValue);
IsUsed(ref myValue);
}
あるいは、コードが適切に破棄されることに問題がないのであれば、以下のように BurstedMethod
に関する警告を無視することもできます。
[IgnoreWarning(1371)]
[BurstCompile]
void BurstMethod()
{
var myValue = BurstCompiledCode(1,3);
DoSomeManagedStuff(myValue);
}