GCC7ではエラーメッセージが改善されるらしい

プログラムを書いているときには当然色々ミスをするが、GCC(gcc/g++)が出すメッセージは Clang(clang/clang++)に比べて分かりにくい/不親切なことが多い。

例えば、FooBarという名前のクラスが宣言されていて、それを使おうとしたときに以下のように間違ってFooBazと書いたとする。

int main(int, char**){
    FooBaz foobar;
}

g++-5.4.0でコンパイルした場合のメッセージは以下のようになる。

g++ -g -Wall -Wextra   -c -o main.o main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:9:5: error: 'FooBaz' was not declared in this scope
     FooBaz foobar;
     ^

最新のg++-6.2では、エラーの位置を示す'^'が波線(~~~~~~)になるが、内容は特に変わらない。

/usr/local/gcc-6.2.0/bin/g++ -g -Wall -Wextra   -c -o main.o main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:9:5: error: 'FooBaz' was not declared in this scope
     FooBaz foobar;
     ^~~~~~

clang++-3.8では以下のように修正候補を挙げてくれる。

clang++ -g -Wall -Wextra   -c -o main.o main.cpp
main.cpp:9:5: error: unknown type name 'FooBaz'; did you mean 'FooBar'?
    FooBaz foobar;
    ^~~~~~
    FooBar
main.cpp:3:7: note: 'FooBar' declared here
class FooBar {
      ^
1 error generated.

あるいは、以下のように文末のセミコロンを忘れた場合、

int main(int, char**){
    FooBaz foobar
    foobar.method1();
}

g++-5.4、g++-6.2、clang++-3.8でコンパイルした結果はそれぞれ以下のようになる。

# g++-5.4
g++ -g -Wall -Wextra   -c -o main.o main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:10:5: error: expected initializer before 'foobar'
     foobar.method1();
     ^

# g++-6.2
/usr/local/gcc-6.2.0/bin/g++ -g -Wall -Wextra   -c -o main.o main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:10:5: error: expected initializer before 'foobar'
     foobar.method1();
     ^~~~~~

# clang++-3.8
clang++ -g -Wall -Wextra   -c -o main.o main.cpp
main.cpp:9:18: error: expected ';' at end of declaration
    FooBar foobar
                 ^
                 ;
1 error generated.

g++では、セミコロンを忘れた行の次の行がエラーとなっているが(普通に解析したらそうなるだろう)、clang++ではちゃんと「セミコロンがない」というメッセージになっている。

これがClangを使う一つの理由だったのだが、Phoronixの記事によれば、GCC7ではエラーメッセージか改善され、タイプミスに対する修正のヒント(Fix-it hints)を出すようになるらしい。

また、その場所にアンダーラインが引かれる、セミコロンがないことに関するFix-it hintsを出す、などと書かれているで、多分Clangと似たような感じになるのだろう。

一昔前まで、フリーで使えるC/C++コンパイラと言えばGCC一択だったところにClangの登場し、GCCにない機能が色々使えるようになったが、それに刺激されたGCCも改善が進んでいるようだ。