コンパイラエラー

C言語 コンパイラ エラー C2180について解説

この記事は、C言語で発生するコンパイラ エラー C2180について説明します。

if、while、for、doなどの制御文で、制御式に(void)を使用すると、bool値またはboolに変換可能な型にならずエラーが発生します。

例えば、while((void)1)のような記述はエラーとなります。

正しい制御式の記述方法を見直すことが重要です。

エラー原因の解説

コンパイラ エラー C2180のメッセージ内容

コンパイラ エラー C2180は、if、while、for、do‐whileなどの制御文の条件部分(制御式)に、(void)キャストを伴う式が指定された場合に発生します。

エラーメッセージには「制御式には、型 void が指定されています」という内容が表示され、ブール値として評価できないため、制御文として使用できないことを示しています。

voidキャストが及ぼす影響

(void)キャストは、本来、関数の戻り値や計算結果を意図的に無視するために使用される記法です。

しかし、制御文の制御式として使用すると、キャスト後の型がvoidになるため、条件式として必要な真偽判定(ブール値)を提供できません。

その結果、コンパイラは制御式の型が不適切であると判断し、エラー C2180を発生させます。

制御文におけるエラー事例

if文でのケース

if文の制御式に(void)キャストを使用すると、条件が適切に評価されずエラーが発生します。

たとえば、下記のコードはif ((void)1)として記述されているためエラーになります。

#include <stdio.h>
int main(void) {
    // if文の制御式に(void)キャストが使用される例
    if ((void)1) {  // エラー C2180 が発生する
        printf("条件は成立です\n");
    }
    return 0;
}
コンパイル時にエラーが発生します: 制御式には、型 'void' が指定されています

while文での誤った記述例

while文における(void)キャストの使用例

while文でも同様に、制御式に(void)キャストを使用するとエラーが生じます。

下記の例では、while ((void)1)と記述されたため、条件がvoid型となりコンパイルできません。

#include <stdio.h>
int main(void) {
    // while文の制御式に(void)キャストを使用した例
    while ((void)1) {  // エラー C2180 が発生する
        printf("ループ内です\n");
        break;
    }
    return 0;
}
コンパイル時にエラーが発生します: 制御式には、型 'void' が指定されています

正しい制御式への変更方法

エラーを回避するためには、(void)キャストを削除して条件式にブール値に評価できる式を用いる必要があります。

定数値1はC言語では非ゼロとして真と評価されるため、下記のように記述するのが適切です。

#include <stdio.h>
int main(void) {
    // 正しい制御式の例: 定数1は非ゼロとして真と評価される
    while (1) {
        printf("ループ内です\n");
        break;
    }
    return 0;
}
ループ内です

for文およびdo-while文での注意点

for文やdo-while文においても、同様の問題が発生する可能性があります。

たとえば、for文の条件部分やdo-while文の制御式に(void)キャストが含まれると、コンパイラはブール値に変換できないと判断します。

正しい記述方法として、キャストを使用せずに条件そのものを記述するか、必要に応じて明示的なブール変換(たとえば、(i < 10))を行う必要があります。

下記は、for文とdo-while文における誤った記述例と改善例のサンプルです。

誤った for文 の例

#include <stdio.h>
int main(void) {
    // for文の条件に(void)キャストを使用するとエラーになる
    for (int i = 0; (void)(i < 10); i++) {  // エラー C2180 が発生する
        printf("i = %d\n", i);
        if (i == 5) break;
    }
    return 0;
}
コンパイル時にエラーが発生します: 制御式には、型 'void' が指定されています

誤った do-while文 の例

#include <stdio.h>
int main(void) {
    int count = 0;
    do {
        printf("count = %d\n", count);
        count++;
    } while ((void)(count < 3));  // エラー C2180 が発生する
    return 0;
}
コンパイル時にエラーが発生します: 制御式には、型 'void' が指定されています

正しい方法としては、各制御式から(void)キャストを取り除いて、下記のように記述します。

正しい for文 の例

#include <stdio.h>
int main(void) {
    // for文の条件部分はキャストを用いず、直接ブール値が評価される式を利用する
    for (int i = 0; i < 10; i++) {
        printf("i = %d\n", i);
        if (i == 5) break;
    }
    return 0;
}
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5

正しい do-while文 の例

#include <stdio.h>
int main(void) {
    int count = 0;
    do {
        printf("count = %d\n", count);
        count++;
    } while (count < 3);  // 正しい制御式
    return 0;
}
count = 0
count = 1
count = 2

エラー修正の具体例

誤ったコード例の解析

キャスト使用時の型エラー詳細

誤ったコードでは、(void)キャストによって式全体の型がvoidとなります。

制御文はブール値(またはそれに準ずる値)によって条件評価を行う必要があるため、void型は評価不可能です。

結果として、「制御式には、型 void が指定されています」というエラーメッセージが表示され、どこで意図しないキャストが行われているのか把握するヒントとなります。

修正後のコード例の提示

ブール値を利用した正しい制御式

修正方法として、制御式から(void)キャストを取り除くか、もともと意図していた条件式をブール値(または、非ゼロで真と評価される値)に変更する必要があります。

下記のコードは、while (1)という表記によって、無限ループの条件が正しく評価される例です。

#include <stdio.h>
int main(void) {
    // 修正後のコード例: 定数1は非ゼロのため、真として評価される
    while (1) {
        printf("ループ内です\n");
        break;
    }
    return 0;
}
ループ内です

開発時の注意事項

コーディングでのエラー回避ポイント

・制御文に不要な(void)キャストが含まれていないか注意する

・制御式の評価結果がブール値として適切か確認する

・定数や変数の型変換が意図通りに行われているか検討する

コンパイラエラーメッセージの読み解き方

エラーメッセージには、どの部分で型不整合が発生しているかが示されています。

特に、「制御式には、型 void が指定されています」というメッセージは、制御文内でのキャスト使用が原因である可能性を示唆しています。

エラーメッセージをよく読み、どの記述が不適切なのかを特定することで、効率的に修正箇所を見つけることが可能となります。

まとめ

この記事では、コンパイラ エラー C2180の原因とその解決方法について学べます。

主に、制御文において(void)キャストが使用された場合に発生するエラーと、その具体的な修正例を取り上げています。

if、while、for、do-while各文での誤った記述例と、ブール値を利用した正しい制御式への変更方法を具体的なサンプルコードで示しているため、今後のコーディングで同様のエラーを防ぐための知識が身につきます。

関連記事

Back to top button
目次へ