この記事では、次のコンパイラ診断について説明します。
- CS0193: * または -> 演算子をポインターに適用する必要があります
- CS0196: ポインターは 1 つの値でのみインデックスを作成する必要があります
- CS0208: マネージド型 ('type') のアドレスを取得したり、サイズを取得したり、ポインターを宣言したりすることはできません。
-
CS0209:
fixedステートメントで宣言されたローカルの型はポインター型である必要があります -
CS0210:
fixedまたはusingステートメント宣言で初期化子を指定する必要があります - CS0211: 指定された式のアドレスを取得できません
-
CS0212:
fixedステートメント初期化子内の固定されていない式のアドレスのみを受け取ることができます -
CS0213:
fixedステートメントを使用して、既に固定された式のアドレスを取得することはできません - CS0214: ポインターと固定サイズ バッファーは、安全でないコンテキストでのみ使用できます
-
CS0227: 安全でないコードは、
/unsafeを使用してコンパイルする場合にのみ表示される場合があります - CS0233: 'identifier' には定義済みのサイズがないため、sizeof は安全でないコンテキストでのみ使用できます
- CS0242: 問題の操作は void ポインターで未定義です
-
CS0244: ポインター型で '
is' と 'as' のどちらも有効ではありません - CS0254: 固定ステートメントの代入式の右側には、キャスト式を使用できません
- CS0459: 読み取り専用ローカル変数のアドレスを取得できません
- CS0821: 暗黙的に型指定されたローカル変数を固定できません
- CS1641: 固定サイズのバッファー フィールドには、フィールド名の後に配列サイズ指定子が必要です
- CS1642: 固定サイズのバッファー フィールドは構造体のメンバーのみである場合があります
- CS1656: 'variable' は '読み取り専用変数型' であるため、'variable' に割り当てることができません
-
CS1663: 固定サイズバッファーの種類は、
bool、byte、short、int、long、char、sbyte、ushort、uint、ulong、float、またはdoubleのいずれかである必要があります。 - CS1664: 長さ 'length' と型 'type' の固定サイズ バッファーが大きすぎます
- CS1665: 固定サイズ バッファーの長さが 0 より大きい必要があります
- CS1666: 固定されていない式に含まれる固定サイズ バッファーを使用することはできません。fixed ステートメントを使用してみてください。
- CS1708: 固定サイズ バッファーには、ローカルまたはフィールドを介してのみアクセスできます
-
CS1716: '
System.Runtime.CompilerServices.FixedBuffer' 属性を使用しないでください。代わりに 'fixed' フィールド修飾子を使用してください。 - CS1919: 安全でない型 '型名' をオブジェクトの作成で使用できません
-
CS4004: 安全でないコンテキストで
awaitできません - CS7092: 固定バッファーの次元は 1 つだけです。
-
CS8372: プロパティに '
System.Runtime.CompilerServices.FixedBuffer' 属性を使用しない - CS8385: 指定された式を固定ステートメントで使用することはできません
- CS8500: マネージド型 ('type') のアドレスを取得するか、サイズを取得するか、またはその型へのポインターを宣言する
- CS8812: > メソッド グループ 'method' を非関数ポインター型 'type' に変換できません。
- CS9049: 固定フィールドを ref フィールドにすることはできません。
-
CS9123: '
&' 演算子は、非同期メソッドのパラメーターまたはローカル変数では使用しないでください。 - CS9360: この操作は安全でないコンテキストでのみ使用できます
-
CS9361:
stackalloc内の初期化子のないSkipLocalsInit式は、安全でないコンテキストでのみ使用できます -
CS9362: 'member' は '
unsafe' としてマークされているため、安全でないコンテキストで使用する必要があります - CS9363: 'member' は、そのシグネチャにポインターがあるため、安全でないコンテキストで使用する必要があります
- CS9364: 安全でないメンバー 'member' は、安全なメンバー 'member' をオーバーライドできません
- CS9365: 安全でないメンバー 'member' は、安全なメンバー 'member' を暗黙的に実装できません
- CS9366: 安全でないメンバー 'member' は、安全なメンバー 'member' を実装できません
-
CS9367:
RequiresUnsafeAttributeはこのシンボルに適用できません。 -
CS9368:
RequiresUnsafeAttributeは、更新されたメモリ安全規則でのみ有効です。 -
CS9376: 'ジェネリック型またはメソッド' の型パラメーター 'type parameter' の '
new()' 制約を満たすために、'unsafe' としてマークされたコンストラクター 'constructor' に安全でないコンテキストが必要です -
CS9377: '
unsafe' 修飾子は、現在のメモリ安全規則では影響を与えません。 -
CS9379: ソースで '
RequiresUnsafeAttribute' を使用しないでください。代わりに 'unsafe' 修飾子を使用してください。 -
CS9388: '
safe' 修飾子は、'extern' とマークされていない 'unsafe' メンバーでのみ使用できます。 -
CS9389: '
extern' メンバーは、'unsafe' または 'safe' としてマークする必要があります。 -
CS9390: 両方の部分メンバー宣言を '
safe' としてマークする必要があります。また、どちらも 'safe' としてマークすることはできません -
CS9392: 明示的または拡張レイアウト型のフィールドは、'
unsafe' または 'safe' としてマークする必要があります。 -
CS9396: プロパティまたはインデクサー 'property' とそのアクセサーの両方に '
unsafe' 修飾子または 'safe' 修飾子を指定できません。そのうちの 1 つを削除します。 -
CS9397: プロパティまたはインデクサー 'property' のすべてのアクセサーで、同じ '
unsafe' または 'safe' 修飾子を指定できません。代わりに、その修飾子をプロパティ自体に配置します。 -
CS9398: '
fixed' ステートメントのコンテキストで待機できません
ポインター操作と逆参照
-
CS0193: ポインターに
*演算子または->演算子を適用する必要があります - CS0196: ポインターは 1 つの値でのみインデックスを作成する必要があります
- CS0242: 問題の操作は void ポインターで未定義です
ポインター操作を正しく使用するには、逆参照、インデックス作成、算術演算の規則に従います。 詳細については、「 ポインター型 と 関数ポインター」を参照してください。
-
*または->演算子をデータ ポインターにのみ適用します (CS0193)。 これらの演算子は、非ポイント型または関数ポインターでは使用しないでください。 C/C++ とは異なり、C# では関数ポインターを逆参照することはできません。 - 値が 1 つだけのインデックス ポインター (CS0196)。 ポインターは多次元インデックス作成をサポートしていません。
- void ポインター (CS0242) で未定義の操作を避けます。 たとえば、参照されているデータのサイズがコンパイラで認識されないため、void ポインターをインクリメントしないでください。
ポインター型とマネージド型
- CS0208: マネージド型 ('type') のアドレスを取得したり、サイズを取得したり、ポインターを宣言したりすることはできません。
- CS0233: 'identifier' には定義済みのサイズがないため、sizeof は安全でないコンテキストでのみ使用できます
- CS8500: これは、マネージド型 ('type') のアドレスを取得したり、サイズを取得したり、その型へのポインターを宣言したりしています
ポインターと sizeof 演算子を正しく操作するには、アンマネージ型と適切なコンテキストを使用します。 詳細については、「 アンマネージ型 と sizeof 演算子」を参照してください。
- ポインターはアンマネージ型 (CS0208) でのみ使用します。 マネージド型のアドレスを取得したり、サイズを取得したり、マネージド型へのポインターを宣言したりしないでください。 マネージド型には、参照型のフィールドまたはプロパティを含む参照型と構造体が含まれます。
- サイズがコンパイル時定数 (
sizeof) ではない型を操作する場合は、unsafeコンテキスト内で 演算子を使用します。 - マネージド型 (CS8500) のアドレスの取得、サイズの取得、またはポインターの宣言は避けてください。 この警告 (レベル 4) は、コンパイラがマネージド型に対するポインター操作を検出したときに発生します。 マネージド型は、任意の参照型、または参照型をフィールドまたはプロパティとして含む構造体です。 詳細については、「 アンマネージ型」を参照してください。
ステートメントの使用を修正しました
- CS0209: 固定ステートメントで宣言されたローカルの型はポインター型である必要があります
-
CS0210: 固定または
usingステートメント宣言で初期化子を指定する必要があります - CS0211: 指定された式のアドレスを取得できません
- CS0212: 固定ステートメント初期化子内の固定されていない式のアドレスのみを受け取ることができます
- CS0213: fixed ステートメントを使用して、既に固定された式のアドレスを取得することはできません
- CS0254: 固定ステートメントの代入式の右側には、キャスト式を使用できません
- CS0459: 読み取り専用ローカル変数のアドレスを取得できません
- CS0821: 暗黙的に型指定されたローカル変数を固定できません
- CS1656: 'variable' は '読み取り専用変数型' であるため、'variable' に割り当てることができません
- CS8385: 指定された式を固定ステートメントで使用することはできません
これらのエラーは、 fixed ステートメント を誤って使用した場合に発生します。
fixed ステートメントは、ガベージ コレクターが移動可能な変数を再配置するのを防ぎ、その変数へのポインターを宣言します。 詳細については、「 安全でないコードとポインター」を参照してください。
fixed ステートメントを正しく使用するには:
- 変数をポインター型として宣言します (CS0209)。
-
fixedステートメント宣言 (CS0210) で初期化子を指定します。 - 有効な式のアドレスのみを取得します。フィールド、ローカル変数、ポインター間接参照 (CS0211)。 2 つの変数の合計のような計算式のアドレスを取得しないでください。
-
fixedステートメント初期化子 (CS0212) 内でのみ、修正されていない式に対して address-of 演算子を使用します。 - 既に固定された式 (
fixed) では、ステートメントを使用しないでください。unsafeメソッドのローカル変数とパラメーターは、スタック上で既に固定されています。 -
fixed固定ステートメントの代入式の右側にキャスト式を使用しないでください (CS0254)。 - 読み取り専用ローカル変数 (CS0459) のアドレスを取得しないでください。
foreachループ、usingステートメント、およびfixedステートメント内の変数は読み取り専用です。 このエラーは、コンパイラの現在のバージョンでは生成されなくなりました。 -
varステートメント (fixed) では、の代わりに明示的な型を使用します。 -
foreachループ、usingステートメント、fixedステートメント (CS1656) などの読み取り専用コンテキストでは変数に割り当てないでください。 -
fixedステートメント (CS8385) でのピン留めをサポートする式のみを使用します。 式は、アドレス指定可能な変数、文字列、または適切なGetPinnableReferenceメソッドを実装する型である必要があります。
安全でないコンテキストの要件
- CS0214: ポインターと固定サイズ バッファーは、安全でないコンテキストでのみ使用できます
- CS0227: アンセーフ コードは、/unsafe を使用してコンパイルする場合にのみ表示される場合があります
-
CS0244: ポインター型で '
is' も 'as' も有効ではありません - CS1919: 安全でない型 '型名' をオブジェクトの作成で使用できません
-
CS4004: 安全でないコンテキストで
awaitできません -
CS9123: '
&' 演算子は、非同期メソッドのパラメーターまたはローカル変数では使用しないでください - CS9360: この操作は安全でないコンテキストでのみ使用できます
-
CS9361:
stackalloc内の初期化子のないSkipLocalsInit式は、安全でないコンテキストでのみ使用できます -
CS9362: 'member' は '
unsafe' としてマークされているため、安全でないコンテキストで使用する必要があります - CS9363: 'member' は、そのシグネチャにポインターがあるため、安全でないコンテキストで使用する必要があります
-
CS9376: 'ジェネリック型またはメソッド' の型パラメーター 'type parameter' の '
unsafe' 制約を満たすには、'new()' としてマークされたコンストラクター 'constructor' には安全でないコンテキストが必要です -
CS9398: '
fixed' ステートメントのコンテキストで待機できません
これらの診断は、必要な unsafe コンテキストなしで安全でないコード コンストラクトを使用する場合、または安全でない型で許可されていない操作を試みる場合に発生します。 詳細については、「安全でないコードとポインター」および「unsafe キーワード」を参照してください。
- ポインターまたは固定サイズバッファーを使用するメソッド、型、またはコード ブロックを、
unsafeキーワード (CS0214) でマークします。 コンパイラでは、ポインター型または固定サイズのバッファー フィールドで動作するコードに対して、明示的な安全でないコンテキストが必要です。 - プロジェクト設定 (CS0227) で AllowUnsafeBlocks コンパイラ オプションを有効にします。 このオプションを指定しないと、コードが正しい場合でも、コンパイラはすべての
unsafeブロックを拒否します。 - ポインター型 (
is) でas演算子または演算子を使用しないでください。 ポインターは型階層に含まれていないため、これらの型テスト演算子はポインターに対して有効ではありません。 - ポインター型インスタンス (
new) を作成するには、演算子を使用しないでください。 アンマネージ メモリにオブジェクトを作成するには、相互運用機能を使用して、ポインターを返すネイティブ メソッドを呼び出します。 -
CS4004 を従来のガイダンスとして扱います。 C# 14 以前では、安全でないコンテキスト内の
awaitは許可されていません。 C# 15 プレビューのメモリ安全性の変更では、awaitは安全でないコンテキストで許可されるため、この一括制限では現在の規則は説明されなくなりました。 - 非同期メソッド (
&) のパラメーターまたはローカル変数に対して address-of 演算子 () を使用しないでください。 中断ポイントの後に非同期操作が再開されると、スタックに変数が存在しない可能性があります。 - unsafe 構文 (ポインタのデリファレンス、アドレス取得、または非管理型の
sizeofなど) を含む操作は、unsafeキーワードでマークします (CS9360)。 C# 15 の更新されたメモリ安全規則では、コンパイラは安全でないコンテキストを必要とする個々の操作を識別します。 -
unsafe属性が適用されている場合は、初期化子を使用しないstackalloc式に対してSkipLocalsInitキーワードを使用します (CS9361)。 初期化子がない場合、スタック割り当てメモリには初期化されていないデータが含まれます。これは安全でない操作です。 -
unsafe(CS9362) とマークされたメンバーを呼び出すとき、またはシグネチャにポインターを持つメンバー (CS9363) を呼び出すときは、unsafeコンテキストを使用します。 更新されたメモリ安全モデルでは、コンパイラは、署名自体にポインターが含まれている従来の互換性ケースでは、呼び出し元に安全義務を明示的に伝達するメンバーについて CS9362 を報告します。 -
new()制約でunsafe(CS9376) とマークされたコンストラクターを呼び出す必要がある場合は、unsafeコンテキストを使用します。 ジェネリック インスタンス化はコンストラクターを暗黙的に呼び出すので、呼び出し元のコンテキストは安全でない必要があります。 -
awaitをfixedステートメント (CS9398) の本体または初期化子の外側に移動してください。 C# 15 プレビューでは、安全でないコンテキストでawaitできますが、fixedステートメントのピン留め有効期間は非同期の中断ポイントにまたがることはできません。fixedに入る前に操作を待機するか、待機する前にfixedステートメントを終了します。
安全でないメンバーの安全契約
- CS9364: 安全でないメンバー 'member' は、安全なメンバー 'member' をオーバーライドできません
- CS9365: 安全でないメンバー 'member' は、安全なメンバー 'member' を暗黙的に実装できません
- CS9366: 非セーフなメンバー「member」は、セーフなメンバー「member」を実装できません
-
CS9367:
RequiresUnsafeAttributeはこのシンボルに適用できません。 -
CS9368:
RequiresUnsafeAttributeは、更新されたメモリ安全規則でのみ有効です。 -
CS9377: '
unsafe' 修飾子は、現在のメモリ安全規則では影響を受けません。 -
CS9379: ソースで '
RequiresUnsafeAttribute' を使用しないでください。代わりに 'unsafe' 修飾子を使用してください。 -
CS9388: '
safe' 修飾子は、'extern' とマークされていない 'unsafe' メンバーでのみ使用できます。 -
CS9389: '
extern' メンバーは、'unsafe' または 'safe' としてマークする必要があります。 -
CS9390: 両方の部分メンバー宣言を '
safe' としてマークする必要があります。また、どちらも 'safe' とマークすることはできません -
CS9396: プロパティまたはインデクサー 'property' とそのアクセサーの両方に '
unsafe' 修飾子または 'safe' 修飾子を指定できません。そのうちの 1 つを削除します。 -
CS9397: プロパティまたはインデクサー 'property' のすべてのアクセサーで、同じ '
unsafe' または 'safe' 修飾子を指定できません。代わりに、その修飾子をプロパティ自体に配置します。
これらの診断では、安全でないとマークされたメンバーに対して C# 15 の安全コントラクト規則が適用されます。 コンパイラは、安全でないメンバーが基底クラスとインターフェイスによって確立された安全性の期待に違反しないようにします。 詳細については、「安全でないコードとポインター」および「unsafe キーワード」を参照してください。
- 安全な基本メンバーを非安全なメンバー (CS9364) でオーバーライドしてはなりません。 オーバーライドは、基底メンバーの安全性契約を維持しなければなりません。 基本メンバーが安全な場合は、オーバーライドも安全である必要があります。 オーバーライドするメンバーから
unsafe修飾子またはRequiresUnsafeAttributeを削除するか、基本メンバーを安全でないとしてマークします。 - 安全でないメンバー (CS9365) を持つ安全なインターフェイス メンバーを暗黙的に実装しないでください。 型がインターフェイス メンバーを暗黙的に実装する場合、インターフェイスを介した呼び出し元は安全な操作を期待します。 実装するメンバーから安全でない指定を削除するか、明示的なインターフェイス実装を使用します。
- 安全でないメンバー (CS9366) を持つ安全なインターフェイス メンバーを明示的に実装しないでください。 明示的な実装でも、インターフェイス メンバーの安全コントラクトを保持する必要があります。
- サポートされているシンボルの種類 (
RequiresUnsafeAttribute) にのみを適用します。 この属性は、メソッド、プロパティ、イベント、コンストラクター、および型に適用できますが、すべてのシンボルの種類でサポートされているわけではありません。 -
RequiresUnsafeAttribute(CS9368) を使用するように更新されたメモリ安全規則を有効にします。 この属性は C# 15 の洗練されたメモリ安全性モデルの一部であり、レガシ ルールでは認識されません。 プロジェクトで、更新されたルールをサポートする言語バージョンをターゲットにしていることを確認します。 - 効果がない場合は、
unsafe修飾子を削除します (CS9377)。 現在のメモリ安全規則では、特定のコンテキストでは、unsafe修飾子を必要とせず、利点も得られません。 不要な注釈をクリーンアップできるように、修飾子が無意味な場合、コンパイラによって警告が表示されます。 - ソース (
unsafe) でRequiresUnsafeAttributeを適用する代わりに、メンバー宣言で直接修飾子を使用します。 この属性はメタデータ表現のみを対象としています。ソース コードでは、unsafeキーワードが正しいメカニズムです。 -
safe修飾子は、まだexternマークされていないunsafeメンバーにのみ適用します (CS9388)。safe修飾子は、extern 宣言に既定で適用される unsafe 前提の対象から extern メンバーを明示的に除外します。 - すべての
externメンバーをunsafeまたはsafe(CS9389) としてマークします。 更新されたメモリ安全規則では、コンパイラが実装を検証できないため、extern メンバーは安全コントラクトを明示的に宣言する必要があります。 - 両方の部分メンバー宣言が
safe修飾子 (CS9390) に同意していることを確認します。 一方の部分宣言がsafeマークされている場合は、一貫した安全契約を維持するために、もう一方の宣言もsafeマークする必要があります。 - プロパティまたはインデクサー、またはアクセサーに
unsafeまたはsafeを配置しますが、両方は配置しません (CS9396)。 プロパティがすべてのアクセサーのコントラクトを設定する場合は、プロパティ自体に修飾子を配置します。 アクセサーが 1 つだけ異なる場合は、そのアクセサーに修飾子を配置し、プロパティを変更しないでください。 - プロパティまたはインデクサーのすべてのアクセサーに同じ
unsafeまたはsafe修飾子がある場合は、その修飾子をプロパティまたはインデクサー宣言 (CS9397) に移動します。 アクセサー修飾子は、アクセサーが意図的に異なる場合にのみ使用します。
明示的または拡張レイアウトフィールド
-
CS9392: 明示的または拡張レイアウト型のフィールドは、'
unsafe' または 'safe' としてマークする必要があります。
この診断は、インスタンス フィールドが明示的または拡張レイアウトに参加していて、そのフィールドが unsafe か safeかを宣言に示さない場合に、更新されたメモリセーフ モデルで発生します。 詳細については、「安全でないコードとポインター」および「safe キーワード」を参照してください。
-
[StructLayout(LayoutKind.Explicit)]または[ExtendedLayout]を持つ型のすべてのインスタンス フィールドをunsafeまたはsafe(CS9392) としてマークします。 フィールドが自動プロパティ、フィールドに基づくプロパティ、プライマリ コンストラクター パラメーター、またはフィールドに似たイベント用に合成される場合は、その生成されたフィールドを所有するプロパティ、パラメーター、またはイベントに修飾子を配置します。
固定サイズ バッファー
- CS1641: 固定サイズのバッファー フィールドには、フィールド名の後に配列サイズ指定子が必要です
- CS1642: 固定サイズのバッファー フィールドは構造体のメンバーのみである場合があります
-
CS1663: 固定サイズバッファーの種類は、
bool、byte、short、int、long、char、sbyte、ushort、uint、ulong、float、またはdoubleのいずれかである必要があります。 - CS1664: 長さ 'length' と型 'type' の固定サイズ バッファーが大きすぎます
- CS1665: 固定サイズ バッファーの長さが 0 より大きい必要があります
- CS1666: 固定されていない式に含まれる固定サイズ バッファーを使用することはできません。fixed ステートメントを使用してみてください。
- CS1708: 固定サイズ バッファーには、ローカルまたはフィールドを介してのみアクセスできます
-
CS1716: '
System.Runtime.CompilerServices.FixedBuffer' 属性を使用しないでください。代わりに 'fixed' フィールド修飾子を使用してください。 - CS7092: 固定バッファーの次元は 1 つだけです。
-
CS8372: プロパティに '
System.Runtime.CompilerServices.FixedBuffer' 属性を使用しない - CS9049: 固定フィールドを ref フィールドにすることはできません。
これらのエラーは、固定サイズのバッファーを操作するときに発生します。 固定サイズ バッファーは構造体に直接埋め込まれた配列であり、主に相互運用シナリオに使用されます。 詳細については、「 固定サイズバッファー」を参照してください。
固定サイズバッファーを正しく宣言して使用するには:
- 正の整数定数 (CS1641、CS1665) を使用して、フィールド名の後の配列サイズ を指定します。 バッファーの合計サイズ (要素数に要素サイズを乗算) は、2^31 バイト (CS1664) を超えてはなりません。
- 固定サイズ バッファーは、クラスではなく構造体でのみ宣言します (CS1642)。 クラスにフィールドが必要な場合は、通常の配列を使用します。
- サポートされている要素の種類 (
bool、byte、short、int、long、char、sbyte、ushort、uint、ulong、float、またはdouble( CS1663) のいずれかを使用します。 - バッファー (
fixed) にアクセスする前に、 ステートメントを使用して包含構造体をピン留めします。 - 固定サイズ バッファーには、中間式 (CS1708) ではなく、ローカルまたはフィールド経由でのみアクセスします。
-
fixed属性 (System.Runtime.CompilerServices.FixedBuffer) の代わりに、 フィールド修飾子を使用します。 この属性はプロパティにも適用しないでください (CS8372)。 - 1 次元のみの固定バッファーを宣言します (CS7092)。 多次元固定バッファーはサポートされていません。
- 固定サイズのバッファーを
refフィールドとして宣言しないでください (CS9049)。 固定サイズバッファーは値フィールドである必要があります。
関数ポインター
- CS8812: > メソッド グループ 'method' を非関数ポインター型 'type' に変換できません。
関数ポインターを取得するには、明示的な関数ポインター型キャストで address-of 演算子を使用します。
address-of 演算子&を使用して、メソッド グループをvoid*またはその他の非関数ポインター型に割り当てないでください。 詳細については、「 関数ポインター」を参照してください。
.NET