【忘備録】コメントのせいでエラーが発生していた【C言語】

スポンサーリンク
homeimage 忘備録
スポンサーリンク

はじめに

どうも、けーとらです。

最近、同期に質問されて、久々にダメ文字のエラーを見つけたので共有。

なんかエラーになるんだけど!?

と言いながら、同期に見せられたコードはこんな感じ。(流石に業務のコードは出せないからね)

#include <stdio.h>

//テスト機能
int iFuncTest();

//メイン
int main()
{
    //テストの実行
    printf("テストの実行\n");
    iFuncTest();

    return 0;
}

//テスト機能
int iFuncTest(){
    
    //結果の出力
    printf("テスト結果");

    return 0;
}

一見何の問題もなさそうで、VisualStudio上では構文エラーなども出ていない様子。

エラー内容

そしてエラーはこんな感じ。

./Main.c:10:5: warning: implicit declaration of function 'iFuncTest' is invalid in C99 [-Wimplicit-function-declaration]
    iFuncTest();
    ^
./Main.c:19:12: error: expected parameter declarator
    printf("テスト結果");
           ^
./Main.c:19:12: error: expected ')'
./Main.c:19:11: note: to match this '('
    printf("テスト結果");
          ^
./Main.c:19:5: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
    printf("テスト結果");
    ^
./Main.c:19:5: error: conflicting types for 'printf'
/usr/include/stdio.h:318:12: note: previous declaration is here
extern int printf (const char *__restrict __format, ...);
           ^
./Main.c:21:5: error: expected identifier or '('
    return 0;
    ^
./Main.c:22:1: error: extraneous closing brace ('}')
}
^
2 warnings and 5 errors generated.

コードには問題ないし…と5分くらい経ってから、あることに気が付いた。

VisualStudioでコーディング、別のコンパイラでコンパイルしているらしい。

なるほど、原因把握しました。

解決

最近は滅多に見なくなったのですが、所謂ダメ文字(後述)ですね。

てことで、16行目のコメントを「//」ではなく「/*」 と「*/」で囲う形にして解決。

#include <stdio.h>

/*テスト機能*/
int iFuncTest();

//メイン
int main()
{
    //テストの実行
    printf("テストの実行\n");
    iFuncTest();

    return 0;
}

/*テスト機能*/
int iFuncTest(){
    
    //結果の出力
    printf("テスト結果");

    return 0;
}

解決の報告だけしても仕方ないので、このようなバグが起こる原因を解説していきます。

C言語のコメント

最近では「//」も「/*」と「*/」で囲ってもコメントとして認識されます。

ただし、「//」はC++から輸入したもので、C99から利用できるようになりました。このため、組み込み系などでC99以前のC言語規格を利用する場合には「//」は使えないことを頭に入れておきましょう。

ダメ文字の原因となっているのはC言語の仕様で、「\」があると継続行とみなされて次の行を含めて1行だと認識することです。

この仕様が「//」コメントでも適用されてしまうため、次のように「//」コメントの最後に「\」があると次の行もコメントアウトされます。

#include <stdio.h>

int main()
{
    //次の行は実行されない\
    printf("実行されない");
    printf("実行される");

    return 0;
}

実行結果は次のようになり、6行目がコメントアウトされていることが分かります。

実行される

Shift JISのダメ文字

ここで問題になるのがShift JISの文字コードです。

Shift JISの2byte目には、C言語のメタ文字(特殊な意味を持つ文字)と同じバイト列が含まれることがあります。

例えば「表」や「能」は2byte目が「\」であり、これは先ほどのC言語の仕様にすると継続行としての意味を持ちます。このような文字のことをダメ文字と言い、Shift JIS特有の現象です。

これらを踏まえると次のコードが納得できるはずです。

#include <stdio.h>

int main()
{
    //次の行は実行されない機能
    printf("実行されない");

    //結果一覧表
    //この行を消すと実行されない
    printf("実行される");

    return 0;
}

解決方法として

文字コードをUTF-8にするのが一番の解決策です。

どうしてもShift JISにこだわる必要があるのであれば、

  • プログラム内に日本語を記述しない
  • 「/*」と「*/」でコメントする

とかですかね。

最後に

なんでSJISのプログラムを使っていたのかは不明ですが、ダメ文字とかは当然把握しているべき事項でコーディング規約にも載ってなかったみたいです。

コードとは異なる部分が原因のエラーがたくさんあるから気をつけようねって感じですかね。

コメント

タイトルとURLをコピーしました