はじめに
この一連の作業は、
「コードコンプリート」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++は何を含み、何を含まないかを確認する作業です。
出力に基づく確認は、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++N4606 一覧
C++N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(1) Sample code compile list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/
###C++N3242 2011 sample code compile list(一覧)
C++2011が出て、コンパイラが対応し始めたころ、N3242のコード断片をコンパイルしながら、C++2011の内容と、コンパイラの対応状況の調査を始めました。
Templateの断片のコンパイル方法がうまくなく、コンパイルエラーの儘になっています。今回、C++N4606を-std=C++03, -std=C++11, -std=C++17でコンパイルする中で意味のある出力を出す方法を検討しています。
https://qiita.com/kaizen_nagoya/items/685b5c1a2c17c1bf1318
C++N3242 C++2011
C++2011まではTrigraph sequencesの規定があった。
N3242(C++2011) 2.4 Trigraph sequences
N3242(C++2011) 2.5 Preprocessing tokens
Compiler
clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
g++-7 --version
g++-7 (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
2 Lexical conventions
2.4 Preprocessing tokens
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
#include <iostream>
// from here p.20
#define R "x"
const char* s = R"y"; // ill-formed raw string, not "x" "y"
/// to here p.20
int main(int argc, char *argv[], char *envp[]){
std::cout << "s=" << s <<std::endl;
std::cout << "R="<< R << std::endl;
return EXIT_SUCCESS;
}
./cppgl.sh p20
$ clang++ p20.cpp
p20.cpp:8:34: error: invalid character ' ' character in raw string delimiter; use
PREFIX( )PREFIX to delimit raw string
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
p20.cpp:8:17: error: expected expression
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
2 errors generated.
$ g++-7 p20.cpp
p20.cpp:8:35: error: invalid character ' ' in raw string delimiter
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
p20.cpp:8:17: error: stray 'R' in program
-std=C++03ではコンパイルできた記録あり。
https://researchmap.jp/joowfvbfr-1797580/#_1797580
再現試験のため、03,11,17でコンパイルするスクリプトを記述
#!/bin/sh
echo "$ clang++ $1.cpp -std=c++03 -Wall"
clang++ $1.cpp -std=c++03 -Wall -o $1l03
if [ -e $1l03 ]; then
./$1l03 $2
fi
echo "$ clang++ $1.cpp -std=c++11 -Wall"
clang++ $1.cpp -std=c++11 -Wall -o $1l11
if [ -e $1l11 ]; then
./$1l11 $2
fi
echo "$ clang++ $1.cpp -std=c++17 -Wall"
clang++ $1.cpp -std=c++17 -Wall -o $1l17
if [ -e $1l17 ]; then
./$1l17 $2
fi
echo "\r"
echo "$ g++-7 $1.cpp -std=c++03 -Wall"
g++-7 $1.cpp -std=c++03 -Wall -o $1g03
if [ -e $1g03 ]; then
./$1g03 $2
fi
echo "\r"
echo "$ g++-7 $1.cpp -std=c++11 -Wall"
g++-7 $1.cpp -std=c++11 -Wall -o $1g11
if [ -e $1g11 ]; then
./$1g11 $2
fi
echo "\r"
echo "$ g++-7 $1.cpp -std=c++17 -Wall"
g++-7 $1.cpp -std=c++17 -Wall -o $1g17
if [ -e $1g17 ]; then
./$1g17 $2
fi
結果はclang++では実行可能。g++で EXIT_SUCCESSがないというエラー。
$ ./cppall.sh p20
$ clang++ p20.cpp -std=c++03 -Wall
s=xy R=x
$ clang++ p20.cpp -std=c++11 -Wall
p20.cpp:8:34: error: invalid character ' ' character in raw string delimiter; use PREFIX(
)PREFIX to delimit raw string
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
p20.cpp:8:17: error: expected expression
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
2 errors generated.
$ clang++ p20.cpp -std=c++17 -Wall
p20.cpp:8:34: error: invalid character ' ' character in raw string delimiter; use PREFIX(
)PREFIX to delimit raw string
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
p20.cpp:8:17: error: expected expression
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
2 errors generated.
$ g++-7 p20.cpp -std=c++03 -Wall
p20.cpp: In function 'int main(int, char**, char**)':
p20.cpp:13:10: error: 'EXIT_SUCCESS' was not declared in this scope
return EXIT_SUCCESS;
^~~~~~~~~~~~
$ g++-7 p20.cpp -std=c++11 -Wall
p20.cpp:8:35: error: invalid character ' ' in raw string delimiter
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
p20.cpp:8:17: error: stray 'R' in program
$ g++-7 p20.cpp -std=c++17 -Wall
p20.cpp:8:35: error: invalid character ' ' in raw string delimiter
const char* s = R"y";//ill-formed raw string, not "x" "y"
^
p20.cpp:8:17: error: stray 'R' in program
プリプロセッサ出力スクリプト
#!/bin/sh
echo " usege ./cppwa17e.sh prog"
echo "$ clang++ $1.cpp -E -std=c++17 -Wall"
clang++ $1.cpp -std=c++17 -E -Wall
echo "\r"
echo "$ g++-7 $1.cpp -E -std=c++17 -Wall"
g++-7 $1.cpp -std=c++17 -E -Wall
出力。
参考資料
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
Clang/Clang++(LLVM) gcc/g++(GNU) コンパイラ警告等比較
https://qiita.com/kaizen_nagoya/items/9a82b958cc3aeef0403f
Qiitaに投稿するCのStyle例(暫定)
https://qiita.com/kaizen_nagoya/items/946df1528a6a1ef2bc0d
MISRA C++ 5-0-16
https://qiita.com/kaizen_nagoya/items/7df2d4e05db724752a74
C++ Templates Part1 BASICS Chapter 3. Class Templates 3.2 Use of Class Template Stack stack1test.cpp
https://qiita.com/kaizen_nagoya/items/cd5fc49106fad5a4e9ed
ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed)
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1
C言語(C++)に対する誤解、曲解、無理解、爽快。
https://qiita.com/kaizen_nagoya/items/3f3992c9722c1cee2e3a
C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識
https://qiita.com/kaizen_nagoya/items/d89a48c1536a02ecdec9
'wchar.h' file not found で困った clang++ macOS
https://qiita.com/kaizen_nagoya/items/de15cd46d657517fac11
Open POSIX Test Suiteの使い方を調べはじめました
https://qiita.com/kaizen_nagoya/items/644d5e407f5faf96e6dc
MISRA-C 2012 Referenceに掲載している文献の入手可能性を確認
https://qiita.com/kaizen_nagoya/items/96dc8b125e462d5575bb
どうやって MISRA Example Suiteをコンパイルするか
https://qiita.com/kaizen_nagoya/items/fbdbff5ff696e2ca7f00
MISRA C まとめ #include
https://qiita.com/kaizen_nagoya/items/f1a79a7cbd281607c7c9
「C++完全理解ガイド」の同意できること上位10
https://qiita.com/kaizen_nagoya/items/aa5744e0c4a8618c7671
文書履歴
ver. 0.10 初稿 20180408
ver. 0.11 change title and add an URL 2080414
ver. 0.12 researchmapのC++2011の結果と比較。
-Eでプリプロセッサ出力、-std=c++03で実行可能性確認(clang++), g++では別エラー
ver. 0.13 N3243一覧追記 20180427
ver. 0.14 URL追記 20230215
最後までおよみいただきありがとうございました。
いいね 💚、フォローをお願いします。
Thank you very much for reading to the last sentence.
Please press the like icon 💚 and follow me for your happy life.