C言語のコンパイラエラー C2170について解説
エラー C2170 は、C言語のコードで識別子が関数として正しく宣言されていない場合に発生します。
特に、#pragma intrinsic
を関数以外に適用すると、組み込み関数として扱えずエラーとなります。
コードの記述を再確認し、適切に修正することで問題を解決してください。
エラー C2170の概要と原因
C言語において、コンパイラエラー C2170 が発生する場合は、主に関数として宣言されていない識別子に対して #pragma intrinsic
を適用したことが原因です。
Microsoft のコンパイラでは、#pragma intrinsic
は関数にのみ適用できるため、関数以外の項目(例:変数やマクロ)に対して使用するとエラーが出ます。
また、すでに関数として宣言されていない場合にも同じエラーが表示されます。
エラー発生の背景
エラー C2170 は、通常、以下の状況により発生します。
- 関数として宣言されていない識別子に対して
#pragma intrinsic
が使用されている - 非組み込み形式の関数に対して
#pragma intrinsic
が適用されている
これにより、コンパイラは対象の識別子を組み込み関数とみなせず、エラーを出力します。
エラー内容は
`’identifier’ :関数として宣言されていません。
組み込みにすることはできません`
と表示されるため、関数宣言や #pragma intrinsic
の使用箇所の見直しが必要です。
関数宣言と #pragma intrinsic の利用
C言語では、組み込み関数(intrinsic function)として利用するためには、まず正しい関数宣言が必要です。
正しく宣言された関数に対して #pragma intrinsic
を適用することで、コンパイラはその関数を最適化対象として扱うようになります。
関数としての正しい宣言方法
関数を正しく宣言するためには、以下の点に注意します。
- 関数プロトタイプが正しく記述されていること
- 関数の定義と宣言が一致していること
以下に正しい関数宣言の例を示します。
#include <stdio.h>
// 正しい関数宣言
int add(int a, int b);
// intrinsic 対象の関数として宣言
#pragma intrinsic(add)
int main(void) {
// 関数呼び出し
printf("%d\n", add(3, 4));
return 0;
}
// 関数の定義
int add(int a, int b) {
return a + b;
}
この例では、関数 add
が正しく宣言されているため、#pragma intrinsic
を適用してもエラーが発生しません。
#pragma intrinsic の適切な適用箇所
#pragma intrinsic
は関数にのみ適用可能です。
たとえば、変数やマクロに対して適用するとエラーが発生します。
適用箇所としては、必ず対象となる関数が宣言されている場所に記述する必要があります。
以下は不適切な使用例です。
#include <stdio.h>
// 変数に対して #pragma intrinsic を適用(不適切な例)
#pragma intrinsic(globalVar)
int globalVar = 0;
int main(void) {
printf("%d\n", globalVar);
return 0;
}
この例では、globalVar
は関数として宣言されていないため、コンパイラはエラー C2170 を出力します。
正しくは、関数に対してのみ使用する必要があります。
発生事例の検証
問題コードの確認
エラー発生コードの例
以下のコードは、#pragma intrinsic
を不適切な対象に適用したためにエラー C2170 を発生させる例です。
#include <stdio.h>
// 誤った使用例:変数に対して #pragma intrinsic を適用
#pragma intrinsic(globalCounter)
int globalCounter = 0; // 関数宣言ではなく変数宣言
int main(void) {
printf("%d\n", globalCounter);
return 0;
}
このコードをコンパイルすると、エラーメッセージとして
`’globalCounter’ :関数として宣言されていません。
組み込みにすることはできません`
と表示されます。
修正コードの確認
修正後の動作検証
エラーが発生しないようにコードを修正するには、まず対象を正しい関数として宣言する必要があります。
以下は修正後のコード例です。
#include <stdio.h>
// 正しい関数として宣言
int getValue(void) {
return 100;
}
// 関数 getValue に対して intrinsic を適用
#pragma intrinsic(getValue)
int main(void) {
// 修正後の関数呼び出し
printf("%d\n", getValue());
return 0;
}
このコードでは、getValue
が正しく関数として宣言されているため、#pragma intrinsic
を適用してもエラーは発生しません。
また、実行結果は以下のようになります。
100
エラー解消の手法
コード修正のポイント
エラー C2170 を解消するためには、以下のポイントに注意が必要です。
- 関数宣言を正しく行い、対象が関数であることを確認する
#pragma intrinsic
は関数にのみ適用し、変数やマクロには使用しない
これにより、コンパイラに組み込み関数として正しく認識させることができ、エラーの発生を防ぐことができるます。
関数宣言の見直し
関数が正しく宣言されていない場合、#pragma intrinsic
を適用するとエラーが出ます。
必ず以下の点を確認してください。
- 関数プロトタイプが定義されていること
- 関数の定義部分と宣言部分が一致していること
- 余分な記述や誤ったシンボルがないこと
正しい関数宣言の例は、先に示した add
関数や getValue
関数の例のように、宣言と定義が一致している場合です。
#pragma intrinsic の正しい使用方法
#pragma intrinsic
は、関数宣言のすぐ後に記述する必要があります。
また、対象となる関数が組み込みに適した関数でなければなりません。
以下の点に注目してください。
- 関数以外の識別子(変数やマクロ)に適用しない
- 関数の宣言がコンパイラに認識されている状態で使用する
- 社内規定やコンパイラのドキュメントに従った使用方法を確認する
これにより、エラー C2170 の発生を回避でき、プログラムの最適化が正しく行われるようになります。
デバッグ時の確認事項
コンパイラエラーメッセージの解析
エラー発生時は、コンパイラが出力するエラーメッセージを丁寧に確認することが重要です。
エラーメッセージには、どの識別子が関数として宣言されていないかが示されています。
以下の手順で解析するとよいです。
- エラーメッセージ内の識別子が、関数として正しく宣言されているか確認する
- 該当する
#pragma intrinsic
の使用箇所を見直す - コード全体の関数宣言と定義の整合性をチェックする
表にまとめると、以下のようになります。
エラーコード | 内容 |
---|---|
C2170 | ‘identifier’ : 関数として宣言されていません。組み込みにすることはできません。 |
この表を元に、ソースコード内の問題箇所を絞り込むことが可能です。
修正効果の検証方法
エラー修正後は、以下の手順で修正効果の検証を行うと確実です。
- ソースコードを再度コンパイルし、エラーが解消されているか確認する
- プログラムを実行して、期待される出力結果が得られるか検証する
- 可能ならば、デバッグツールを用いて関数呼び出しの挙動を解析する
たとえば、先に示した修正後のサンプルコードを実行し、出力が 100
となることを確認することで、修正が正しく行われたか判断することができます。
まとめ
この記事では、エラー C2170 の原因と対策について解説しています。
特に、関数としての正しい宣言方法や、#pragma intrinsic
の適用場所に注意する必要性を説明し、具体的なサンプルコードを通じて修正例と実行結果を示しました。
これにより、エラーメッセージの意味を理解し、適切な修正方法を把握することができます。