Edited at

C++/C コンパイルエラーを記録するとよい理由7つ

コンパイル言語で設計していて、コンパイルエラーを記録していてよかったことを5つ記録します。

まずC言語とC++の例を記載します。JAVAでも類似の事項に出くわしたことがあります。


1 Compile error driven design

コンパイルエラーのメッセージから、逆にどう記述すればいいかが分かることがある。

4年前に、C++N3242のコード断片をコンパイルしていた時には、何をどうしたらいいか分からなかった。

C++N3242(C++2011)2.14 Literals 2.14.8 User-defined literals

https://researchmap.jp/jov0o7b4c-1797580/#_1797580

今年になって、C++N4606のコード断片をコンパイルしていた時に、とにかく引数と戻り値の型を合わせればコンパイルできることがわかった。

C++N4606 (7) 2.13.8 User-defined literals[lex.ext]p34

https://qiita.com/kaizen_nagoya/items/65f56327c29a1883849a

5月になって、C++N4741のコード断片をコンパイルしていた時に、

p23a.cpp:48:11: error: unable to find string literal operator 'operator""_x' with 'const char [4]', 'long unsigned int' arguments

え、このエラーに合わせた型で定義すればコンパイラ通るの?

ってなった。

実際に、


p23a.cpp

std::string operator "" _w(const char cp[4],long unsigned int sz) {

std::cout << cp << std::endl;
std::string ss;
return ss;
};

"two" _w; // error: no applicable literal operator


他の定義はconst char *なのに、const char cp[4]でいいとは思いつかなかった。他の定義はsize_tなのに、long unsigned intでいいとは思いつかなかった。

これが規格の意図やコンパイラの意図にあっているかどうかは未確認。

でもコンパイルエラーが通ったたけでなく、実行結果は設計者の意図通り。

コンパイルエラーを記録していたおかげです。感謝。


2 Compile error driven design(2)

上記事例では、途中を端折って記録した。

この事例では、8段階をほぼ全て記録。

初めての CEDD(Compile Error Driven Design) 8回直してコンパイル。

https://qiita.com/kaizen_nagoya/items/9494236aa1753f3fd1e1

stackoverflowの例を参考に、constexpreを使う。

「Template argument for non-type parameter must be an expression」

https://stackoverflow.com/questions/37880517/template-argument-for-non-type-parameter-must-be-an-expression

途中、発想の転換のため2度別作業をしている。

合計作業時間は1時間ちょっと。

解決は開始から8時間後。


3 コンパイラによる違いが分かる(benchmark)

コンパイラごとのエラーにする範囲、警告を出す範囲の違いがわかります。

規格への適合の具合の違いがわかります。

ANSI/C 1989, ISO/IEC 9899:1990のC言語規格ができた頃、

Lattice C

Microsoft C

Turbo C

Toshiba Unix C(16bit)

HP Unix C(32bit)

ACOS-6 C(32bit?)

の6種類のCコンパイラのエラー、警告の比較をしていました。

また、Watcom C, Intel Cは利用者の方に規格断片などをコンパイルして、エラー、警告などを教えていただきました。

一番規格に適合していたのがWatcom Cでした。

現在ではオープンになっています。16ビットコンパイラの振る舞いを確認するのに利用しています。

https://github.com/open-watcom/open-watcom-v2


4 文法の許容範囲が分かる(syntax)

規格の文章や、マニュアルでは理解ができないことが多くあります。

実際のプログラムを実際のコンパイラが処理できるかどうかで、現実の問題解決を図ります。

規格への適合ではなく、既存のプログラムをどう表現を変更すれば通るかなど、文法の許容範囲を理解します。


5 版の違いが分かる。(versions)

コンパイラの版がかわって、従来のプログラムのコンパイルエラーの有無が分かる。

コンパイルエラーになるソースを保存して置いて、コンパイラの版がかわって、コンパイルエラーになるかどうかを確かめるとよい。

GCC, LLVM/CLANGのようなコンパイラのソースコード自体をコンパイルするとなおよい。

コンパイラの違い、版の違いが良く分かるかもしれない。


6 OSの違い、文字コードの違い、(OS and character code)

コンパイラの版が同じでもOSが違うとコンパイルエラーが違うことがあります。

C/ C++は、C言語規格に対応したOSであるhosted環境と、C言語がOSを想定しないfreestanding環境とがあります。

 Windows, macOS, Linux, Unixなどはhosted環境です。TOPPERS/SSPなどはfreestanding環境です。

設計する環境と、実行する環境とが異なる場合もあります。CPUが違う場合には、クロス開発と呼びます。

開発するOSと実行するOSの文字コードが違う場合には、処理、ライブラリで注意が必要です。設計環境で模擬試験をしても、実行環境では動かないということがあるかもしれません。

特に、{}[]などの文字コードが扱えない設計環境では、trigraphまたはdigraphを使います。上記でACOS-6のCコンパイラのPCでの通信エミュレータで{}[]などの文字が使えないため、オンラインエディタで編集する場合には、トリグラフを利用していました。PC側でトリグラフを使わずに、C言語でトリグラフ変換ソフトを作って、トリグラフファイルにして、ホストに転送して編集しました。

また、コンパイラ自体はトリグラフではなくてもコンパイルできる可能性があるため、そのまま転送してコンパイルすることも試しました。

PC-VANには記録が残っていましたが、PC-VANが終了した際に、ACOS-6は利用していなかったため、データの移行は行いませんでした。


7 ネットの検索(internet search)

コンパイラのエラーが分からずに、ネットで検索すると、5年前、10年前に自分がネットに記録したことに遭遇することがあります。

残念なのは、その時は解決せずに放置していた記録があることです。

今、新しいコンパイラでコンパイルしてみると、うまくコンパイルでき、時間が解決することがあるのか、自分の操作が十分でなかったかと思うことがあります。

問題を解決しておいた記録は、そうそうと、同じ手順で問題を解決します。

ネットに記録しておいて良かった。

具体例で、現在も残っている記録は順次引用します。


参考文献(reference)

初学者がハマったエラーをまとめてみた【プログラミング学習107日目】

https://qiita.com/fuku_tech/items/0d4f2546cb4ee045c7f7


自己資料(self reference)

プログラミング言語教育のXYZ

https://qiita.com/kaizen_nagoya/items/1950c5810fb5c0b07be4

プログラミング言語教育のXYZ(youtube)

https://www.youtube.com/watch?v=He1_tg4px-w&t=486s

初めての CEDD(Compile Error Driven Design) 8回直してコンパイル。

https://qiita.com/kaizen_nagoya/items/9494236aa1753f3fd1e1

コンパイルエラーを記録するとよい理由7つ

https://qiita.com/kaizen_nagoya/items/85c0e92b206883140e89

C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識

https://qiita.com/kaizen_nagoya/items/d89a48c1536a02ecdec9

C言語(C++)に対する誤解、曲解、無理解、爽快。

https://qiita.com/kaizen_nagoya/items/3f3992c9722c1cee2e3a

Qiitaに投稿するCのStyle例(暫定)

https://qiita.com/kaizen_nagoya/items/946df1528a6a1ef2bc0d

C++N4606 Working Draft 2016, ISO/IEC 14882, C++ standardのコード断片をコンパイルするためにしていること

https://qiita.com/kaizen_nagoya/items/a8d7ee2f2e29e76c19c1

コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)

https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da

[C][C++]の国際規格案の例題をコンパイルするときの課題7つ。

https://qiita.com/kaizen_nagoya/items/5f4b155030259497c4de

docker gnu(gcc/g++) and llvm(clang/clang++)

https://qiita.com/drafts/059874ea39c4de64c0f7


文書履歴(document history)

ver. 0.10 理由3つ 20180428

ver. 0.11 理由3つから理由4つへ(最後に追加) 20180420

ver. 0.12 理由4つから理由5つへ(最初に追加) 20180503

ver. 0.13 誤記訂正、補足追記、章に#記号をつける。 20180504

ver. 0.14 節を章に格上げ、事例1つ追記 20180505

ver. 0.15 参考文献欄追記,見出し英語追記 20180616

ver. 0.16 参考資料、はてなブックマーク追記 20190120

このエントリーをはてなブックマークに追加

http://b.hatena.ne.jp/guide/bbutton