#はじめに
この一連の作業は、
「コードコンプリート」Code Complete 完全なプログラミングを目指して Steve McConnell, Microsoft Press, 2005 978-4891004552
https://www.amazon.co.jp/dp/489100455X/
第二章 ソフトウェア開発への理解を深めるメタファ(比喩)
https://researchmap.jp/jo4lkx7zs-1797580/#_1797580
の「コードを書く」という考え方に基づいています。
写経というよい文化があり、コンパイラやOSを写せば、C言語のかなりの部分が理解できます。いくつかのCコンパイラを写経したり、Pascalで書かれたコンパイラをC言語に書き直したりしてきました。OSは、TOPPERS/SSPという自律(freestnding)環境のOSを書き写してきました。
C言語、C++は肥大化し、それらの記述には現れない機能や関数も出ています。そこで、標準文書のコード断片をコンパイルすることにより、今、C言語、C++は何を含み、何を含まないかを確認する作業です。
hosted環境のプログラムであることを明記せず、freestanding環境ではどうすればいいかが記載できていないことが大きな課題です。
出力に基づく確認は、C言語発祥の地、ベル研究所から出ている3つの主なC文献
Programming language C
C traps and pit fall
The C puzzle book
のなかのThe C Puzzle Bookに基づいています。何かを出力しようとすると副作用は避けられない事があります。出力しようとしなければ起きない現象があるかもしれません。
またコードコンプリート第3章上流工程の必要性、第4章構築の重要な決断における道具の選定に当たって、標準に掲載のあるコードを道具(g++, Clang++)がどのようにコンパイルでき、どういうエラーを出すか洗い出しておくことも大切かもしれません。
HDLではエラーが出るとネットで検索すると適切な修正のサイトや、不具合情報に遭遇することが良くありました。C, C++の警告等ではなかなか遭遇できずにいます。
道具の選定の際には、標準のコードはすべてコンパイルしてあることを具体的にしておくとよい。
C++N4741 Working Draft, Standard for Programming Language C++
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4741.pdf
C++N4606 Working Draft, Standard for Programming Language C++
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/#mailing2016-11
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
C++N3242
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
N4741, N4606, N3242は、ISO/IEC JTC1 SC22 WG21の作業原案(Working Draft)です。
公式のISO/IEC 14882原本ではありません。
ISO/IEC JTC1 SC22 WG21では、可能な限り作業文書を公開し、幅広い意見を求めています。
一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(g++, Clang++)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
また、CERT C++, MISRA C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、Linux OS, TOPPERSカーネル、g++(GCC), clang++(LLVM)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。
##作業方針
1)コンパイルエラーを収集する。
2)コンパイルエラーをなくす方法を検討する。
コンパイルエラーになる例を示すだけが目的のコードは、コンパイルエラーをなくすのではなく、コンパイルエラーの種類を収集するだけにする。
文法を示すのが目的のコード場合に、コンパイルエラーをなくすのに手間がかかる場合は、順次作業します。
3)リンクエラーをなくす方法を検討する。
文法を示すのが目的のコード場合に、リンクエラーをなくすのに手間がかかる場合は、順次作業します。
4)意味のある出力を作る。
コンパイル、リンクが通っても、意味のある出力を示そうとすると、コンパイル・リンクエラーが出て収拾できそうにない場合がある。順次作業します。
1)だけのものから4)まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。
この作業中に出たコンパイルエラーの種類と原因を記録します。
原因別にまず一覧を作り始めます。
#1 ソースコード以外の文字列。
解決:消すか、註釈にする。
##1.1 error: unknown type name 'For'
p168.cpp:48:1: error: unknown type name 'For'
For another example,
^
##1.2 error: expected ';' after top level declarator
p168.cpp:48:12: error: expected ';' after top level declarator
For another example,
^
#2 文字定数’a’のPDFファイルのコードをMacでコピペするとASCIIの'ではない。
##2.1 error: non-ASCII characters are not allowed outside of literals and identifiers
p168.cpp:110:3: error: non-ASCII characters are not allowed outside of literals and identifiers
f(’a’); // OK: D::f(char)
^
##2.1 error: use of undeclared identifier 'a'
p168.cpp:110:6: error: use of undeclared identifier 'a'
f(’a’); // OK: D::f(char)
付随的なエラーである。'に修正すれば、定数と解釈して消える。
#3 複数のコード断片間で同じ、変数、関数名がある
##3.1 error: redefinition of 'i'
p168.cpp:50:5: error: redefinition of 'i'
int i;
^
###3.1.1 Namespaceを分ける。
###3.1.2 別の関数の中に入れる
###3.1.3 ファイルを分ける
C++N3242の例題はファイル名を変更していた。変更誤りなど保守性に課題があったため、上記の3つの方法を優先させている。
##3.2 error: reference to 'B' is ambiguous
p168.cpp:81:17: error: reference to 'B' is ambiguous
using namespace B;
^
複数箇所に関係定義があるため、曖昧(ambiguous)になる。
上記修正でなくなる。
#4 必要なヘッダファイルをincludeしてない。
##4.1 error: 'EXIT_SUCCESS' was not declared in this scope
p97.cpp:21:10: error: 'EXIT_SUCCESS' was not declared in this scope
return EXIT_SUCCESS;
^~~~~~~~~~~~
解決:g++はEXIT_SUCCESSはcstdlibをincludeする必要がある。
##4.2 error: 'assert' was not declared in this scope
p49.cpp:18:1: error: 'assert' was not declared in this scope
assert(p->n == 2); // OK
^~~~~~
p49.cpp:18:1: note: 'assert' is defined in header '<cassert>'; did you forget to '#include <cassert>'?
p49.cpp:8:1:
+#include <cassert>
解決:g++は,assert関数はcassertをincludeする必要がある。
##4.3 error: 'strcmp' is not a member of 'std'
p20.cpp:21:13: error: 'strcmp' is not a member of 'std'
assert(std::strcmp(p, "a\\\nb\nc") == 0);
^~~~~~
解決:g++は, strcmp関数はcstringをincludeする必要がある。
##4.4 error: 'vector' in namespace 'std' does not name a template type
p156.cpp:18:6: error: 'vector' in namespace 'std' does not name a template type
std::vector<double> v = { /* ... */ };
^~~~~~
p156.cpp:18:1: note: 'std::vector' is defined in header '<vector>'; did you forget to '#include <vector>'?
p156.cpp:8:1:
+#include <vector>
解決:vector宣言はvectorをinclude
#5 宣言文に関するエラー
##5.1 error: use of undeclared identifier 'z'
125.cpp:13:17: error: use of undeclared identifier 'z'
complex<double> z;
^
complexは、clang++, g++で対応が異なる。
#6 コンパイルオプションが必要
#6.2 error: 'concept' does not name a type
p97.cpp:14:22: error: 'concept' does not name a type
template concept C =
^~~~~~~
p97.cpp:14:22: note: 'concept' only available with -fconcepts
解決:g++では-fconceptsを書くとconceptのコンパイルエラーが消える。
次の変数でコンパイルエラーになる場合がある。
#7 コンパイルエラーの箇所があるための巻き添え
多数。
Compiler
###clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-apple-darwin17.4.0
###g++-7 --version
g++-7 (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
C++N3242 2011
付属するresearchmapのURLは、C++2011N3242のsample codeを-std=c++11でコンパイル実行した結果です。
一覧は
C++N3242, 2011 sample code compile list on clang++ and g++
https://qiita.com/kaizen_nagoya/items/685b5c1a2c17c1bf1318
使ったコンパイラは
clang++ (clang-503.0.40) (based on LLVM 3.4svn)
g++-4.9 (GCC) 4.9.0 20131229 (experimental)
です。比較し、相互にURLを貼り、相互に教育に使えるような改良を加えるかもしれません。
###C++N4606 standardのコード断片をコンパイルするためにしていること
https://qiita.com/kaizen_nagoya/items/a8d7ee2f2e29e76c19c1
#C++N4606一覧
###(1) this list
C++N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(1) sample coding list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/