#はじめに(Introduction)
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++N4741は、ISO/IEC JTC1 SC22 WG21の作業原案(Working Draft)です。
公式のISO/IEC 14882原本ではありません。
ISO/IEC JTC1 SC22 WG21では、可能な限り作業文書を公開し、幅広い意見を求めています。
一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(g++, Clang++)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
Linux OSなどのhosted環境, TOPPERSカーネルなどのfreestanding環境におけるC++の機能と役割を確認したり、system CによるCPUの記述のtemplateによる再利用を検討しています。
CERT C++, MISRA C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、g++(GCC), clang++(LLVM)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。
##背景(back ground)
C/C++でコンパイルエラーが出ると、途方にくれることがしばしばあります。
何回かに1回は、該当するエラーが検索できます。
ただ、条件が違っていて、そこでの修正方法では目的を達成しないこともしばしばです。いろいろな条件のコンパイルエラーとその対応方法について、広く記録することによって、いつか同じエラーに遭遇した時にやくに立つことを目指しています。
この半年の間で、三度、自分のネットでの記録に助けられたことがあります。
また過去に解決できなかった記録を10種類以上、最近になって解決できたことがあります。それは、主に次の4つの情報に基づいています。
https://stackoverflow.com
https://cpprefjp.github.io
http://ja.cppreference.com/
https://teratail.com/
また
https://researchmap.jp/joub9b3my-1797580/#_1797580
に記載したサイトのお世話になっています。
##作業方針(sequence)
Clang++では-std=c++03, c++17, C++2aの3種類
g++では-std=c++03, c++17の2種類
でコンパイルし、
1)コンパイルエラーを収集する。
2)コンパイルエラーをなくす方法を検討する。
コンパイルエラーになる例を示すだけが目的のコードは、コンパイルエラーをなくすのではなく、コンパイルエラーの種類を収集するだけにする。
文法を示すのが目的のコード場合に、コンパイルエラーをなくすのに手間がかかる場合は、順次作業します。
3)リンクエラーをなくす方法を検討する。
文法を示すのが目的のコード場合に、リンクエラーをなくすのに手間がかかる場合は、順次作業します。
4)意味のある出力を作る。
コンパイル、リンクが通っても、意味のある出力を示そうとすると、コンパイル・リンクエラーが出て収拾できそうにない場合がある。順次作業します。
1)だけのものから4)まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。
コーディング標準対応
コーディング標準の検討の下準備のコードとして、
コーディング標準を守って初期化をしてある方がいいという
考え方があります。
ここでは、逆に、コンパイラの警告がどれくらいコーディング標準の検査に役立つかを確かめたいという目的があります。
何か特別なコンパイラを使っていても、将来の可搬性を考えて、
g++, clang++, visual C++の三種類のコンパイラでコンパイルできるか、
三種類のコンパイラの警告は役立たないかを確認したい。
###初期化をしない理由
しばしば変数は初期化していません。
初期化したとしても、なるべく0,1ではなく、それ以外の数を代入するようにしています。コンパイラが、どういう警告を出すか、あるいは場合によってはコンパイルエラーにするかなどを確かめるためです。
こういうコードを実際に書いて欲しいという例ではありません。
###実行する理由
実行する意味があまりなさそうなコードを実行しているのは、実行時のエラーを収集する目的です。コンパイル・リンクは通っても、実行時のエラーに何が発生する可能性があるかを収集します。
万が一、実行時にリンクする仕組みや、空間を確保するとしたら、実行しないと振る舞いがわからないことがあります。
初めての CEDD(Compile Error Driven Design) 8回直してコンパイル。
https://qiita.com/kaizen_nagoya/items/9494236aa1753f3fd1e1
コンパイルエラーを記録するとよい理由7つ
https://qiita.com/kaizen_nagoya/items/85c0e92b206883140e89
##C++N4741, 2018 Standard Working Draft on ISO/IEC 14882 sample code compile list
https://qiita.com/kaizen_nagoya/items/3294c014044550896010
C++N4606, 2016符号断片編纂一覧(example code compile list)
C++N4606, 2016 Working Draft 2016, ISO/IEC 14882, C++ standard(1) Example code compile list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/
##C++N3242, 2011 sample code compile list on clang++ and g++
https://qiita.com/kaizen_nagoya/items/685b5c1a2c17c1bf1318
編纂器(Compiler)
###clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-apple-darwin17.4.0
###g++-8 --version
g++-8 (Homebrew GCC 8.1.0) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
#(173)16.3.3.2 Ranking implicit conversion sequences [over.ics.rank]p298
C++N4606, 2016 (157)13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]p333
https://qiita.com/kaizen_nagoya/items/fe6587c5a6004c80845a
C++N3242, 2011(138) 13.3.3 Best viable function 13.3.3.2 Ranking implicit conversion sequences
https://researchmap.jp/joikp1uz4-1797580/#_1797580
##p298.cpp
###算譜(source code)
// C++N4741 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n741.pdf
const char* msg= "C++N4741(173)16.3.3.2 Ranking implicit conversion sequences [over.ics.rank]p298.cpp";
// Edited by Dr. Ogawa Kiyoshi. Compile procedure and results record.
#include <iostream>
#include <cstdlib>
using namespace std;
namespace N {
void f1(int); // #1
void f1(std::initializer_list<long>); // #2
void g1() {
f1({42}); // chooses #2
}
void f2(std::pair<const char*, const char*>); // #3
void f2(std::initializer_list<std::string>); // #4
void g2() {
f2({"foo","bar"}); // chooses #4
}
}
namespace M {
int i;
int f1();
int&& f2();
int g(const int&);
int g(const int&&);
int j = g(i); // calls g(const int&)
int k = g(f1()); // calls g(const int&&)
int l = g(f2()); // calls g(const int&&)
struct A {
A& operator<<(int);
void p() &;
void p() &&;
};
A& operator<<(A&&, char);
void h() {
A() << 1; // calls A::operator<<(int)
A() << 'c'; // calls operator<<(A&&, char)
A a;
a << 1; // calls A::operator<<(int)
a << 'c'; // calls A::operator<<(int)
A().p(); // calls A::p()&&
a.p(); // calls A::p()&
}
}
namespace P {
int f(void(&)()); // #1
int f(void(&&)()); // #2
void g();
int i1 = f(g); // calls #1
}
namespace Q {
int f(const volatile int *);
int f(const int *);
int i;
int j = f(&i); // calls f(const int*)
}
namespace R {
int f(const int &);
int f(int &);
int g(const int &);
int g(int);
int i;
int j = f(i); // calls f(int &)
int k = g(i); // ambiguous
struct X {
void f() const;
void f();
};
void g(const X& a, X b) {
a.f(); // calls X::f() const
b.f(); // calls X::f()
}
}
namespace S {
struct A {
operator short();
} a;
int f(int);
int f(float);
int i = f(a); // calls f(int), because short ! int is
// better than short ! float.
}
namespace U {
struct A {};
struct B : public A {};
struct C : public B {};
C* pc;
int f(A*);
int f(B*);
int i = f(pc); // calls f(B*)
}
int main() {
M::h();
cout << msg << endl;
return EXIT_SUCCESS;
}
###編纂・実行結果(compile and go)
$ ../c1.sh p298
$ clang++ p298.cpp -std=c++2a -Wall
p298.cpp:68:9: error: call to 'g' is ambiguous
int k = g(i); // ambiguous
^
p298.cpp:64:5: note: candidate function
int g(const int &);
^
p298.cpp:65:5: note: candidate function
int g(int);
^
1 error generated.
#p298a.cpp
コンパイルエラーを想定していた行を///註釈に。
一部の式は、p298.cppでh()の中に入れてある。
警告をなるべく出ないようなreturn true;などを追記。
###算譜(source code)
// C++N4741 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n741.pdf
const char* msg= "C++N4741(173)16.3.3.2 Ranking implicit conversion sequences [over.ics.rank]p298a.cpp";
// Edited by Dr. Ogawa Kiyoshi. Compile procedure and results record.
#include <iostream>
#include <cstdlib>
using namespace std;
namespace N {
void f1(int); // #1
void f1(std::initializer_list<long>) {}; // #2 /// add {} for link error
void g1() {
f1({42}); // chooses #2
}
void f2(std::pair<const char*, const char*>) {}; // #3 /// add {} for link error
void f2(std::initializer_list<std::string>) {}; // #4 U /// add {} for link erro
void g2() {
f2({"foo","bar"}); // chooses #4
}
}
namespace M {
int i;
int&& ia =0;
int f1() {
return i;
};/// add {} for link error
int&& f2() {
return (int &&)ia;
};/// add {} for link error
int g(const int&) {
return true;
};/// add {} for link error
int g(const int&&) {
return false;
};/// add {} for link error
int j = g(i); // calls g(const int&)
int k = g(f1()); // calls g(const int&&)
int l = g(f2()); // calls g(const int&&)
struct A {
A& operator<<(int) {}; /// add {} for link error
void p() & {}; /// add {} for link error
void p() && {}; /// add {} for link error
};
A& operator<<(A&&, char) {}; /// add {} for link error
void h() {
A() << 1; // calls A::operator<<(int)
A() << 'c'; // calls operator<<(A&&, char)
A a;
a << 1; // calls A::operator<<(int)
a << 'c'; // calls A::operator<<(int)
A().p(); // calls A::p()&&
a.p(); // calls A::p()&
}
}
namespace P {
int f(void(&)()) {
return true;
}; // #1 /// add {} for link error
int f(void(&&)()); // #2
void g() {
cout <<"P::g()"<<endl;
}; /// add {} for link error
int i1 = f(g); // calls #1
}
namespace Q {
int f(const volatile int *);
int f(const int *) {
return false;
};/// add {} for link error
int i;
int j = f(&i); // calls f(const int*)
}
namespace R {
int f(const int &) {
return true;
};/// add {} for link error
int f(int &) {
return false;
}; /// add {} for link error
int g(const int &);
int g(int);
int i;
int j = f(i); // calls f(int &)
///int k = g(i); // ambiguous
struct X {
void f() const {
cout <<"R::X::f()const"<<endl;
};/// add {} for link error
void f() {
cout <<"R::X::f()"<<endl;
};/// add {} for link error
};
void g(const X& a, X b) {
a.f(); // calls X::f() const
b.f(); // calls X::f()
}
}
namespace S {
struct A {
operator short() {}; /// add {} for link error
} a;
int f(int) {
return false;
};/// add {} for link error
int f(float);
int i = f(a); // calls f(int), because short ! int is
// better than short ! float.
}
namespace U {
struct A {};
struct B : public A {};
struct C : public B {};
C* pc;
int f(A*);
int f(B*) {
return true;
};/// add {} for link error
int i = f(pc); // calls f(B*)
}
int main() {
M::h();
cout << msg << endl;
return EXIT_SUCCESS;
}
###編纂・実行結果(compile and go)
$ ../cpla.sh p298a
$ clang++ p298a.cpp -std=c++03 -Wall
p298a.cpp:13:6: error: variable has incomplete type 'void'
void f1(std::initializer_list<long>){}; // #2 /// add {} for link error
^
p298a.cpp:13:14: error: no member named 'initializer_list' in namespace 'std'
void f1(std::initializer_list<long>){}; // #2 /// add {} for link error
~~~~~^
p298a.cpp:13:35: error: expected '(' for function-style cast or type construction
void f1(std::initializer_list<long>){}; // #2 /// add {} for link error
~~~~^
p298a.cpp:13:36: error: expected expression
void f1(std::initializer_list<long>){}; // #2 /// add {} for link error
^
p298a.cpp:13:37: error: expected ';' after top level declarator
void f1(std::initializer_list<long>){}; // #2 /// add {} for link error
^
;
p298a.cpp:14:16: error: expected expression
void g1() { f1({42}); } // chooses #2
^
p298a.cpp:16:6: error: variable has incomplete type 'void'
void f2(std::initializer_list<std::string>){}; // #4 U /// add {} for link erro
^
p298a.cpp:16:14: error: no member named 'initializer_list' in namespace 'std'
void f2(std::initializer_list<std::string>){}; // #4 U /// add {} for link erro
~~~~~^
p298a.cpp:16:42: error: expected '(' for function-style cast or type construction
void f2(std::initializer_list<std::string>){}; // #4 U /// add {} for link erro
~~~~~~~~~~~^
p298a.cpp:16:43: error: expected expression
void f2(std::initializer_list<std::string>){}; // #4 U /// add {} for link erro
^
p298a.cpp:16:44: error: expected ';' after top level declarator
void f2(std::initializer_list<std::string>){}; // #4 U /// add {} for link erro
^
;
p298a.cpp:17:16: error: expected expression
void g2() { f2({"foo","bar"}); } // chooses #4
^
p298a.cpp:22:4: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
int&& ia =0;
^
p298a.cpp:24:4: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
int&& f2(){return (int &&)ia;};/// add {} for link error
^
p298a.cpp:24:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
int&& f2(){return (int &&)ia;};/// add {} for link error
^
p298a.cpp:26:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
int g(const int&&){return false;};/// add {} for link error
^
p298a.cpp:32:10: warning: reference qualifiers on functions are a C++11 extension
[-Wc++11-extensions]
void p() &{};/// add {} for link error
^
p298a.cpp:33:10: warning: reference qualifiers on functions are a C++11 extension
[-Wc++11-extensions]
void p() &&{};/// add {} for link error
^
p298a.cpp:35:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
A& operator<<(A&&, char){};/// add {} for link error
^
p298a.cpp:50:12: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
int f(void(&&)()); // #2
^
8 warnings and 12 errors generated.
$ clang++ p298a.cpp -std=c++2a -Wall
p298a.cpp:31:20: warning: control reaches end of non-void function [-Wreturn-type]
A& operator<<(int){};/// add {} for link error
^
p298a.cpp:35:26: warning: control reaches end of non-void function [-Wreturn-type]
A& operator<<(A&&, char){};/// add {} for link error
^
p298a.cpp:82:18: warning: control reaches end of non-void function [-Wreturn-type]
operator short(){};/// add {} for link error
^
3 warnings generated.
../cpla.sh: line 11: 4682 Illegal instruction: 4 ./$1l2a $2
$ g++-8 p298a.cpp -std=c++03 -Wall
p298a.cpp:13:14: error: variable or field 'f1' declared void
void f1(std::initializer_list<long>){}; // #2 /// add {} for link error
^~~~~~~~~~~~~~~~
p298a.cpp:13:14: error: 'initializer_list' is not a member of 'std'
p298a.cpp:13:31: error: expected primary-expression before 'long'
void f1(std::initializer_list<long>){}; // #2 /// add {} for link error
^~~~
p298a.cpp: In function 'void N::g1()':
p298a.cpp:14:16: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
void g1() { f1({42}); } // chooses #2
^
p298a.cpp: At global scope:
p298a.cpp:16:14: error: variable or field 'f2' declared void
void f2(std::initializer_list<std::string>){}; // #4 U /// add {} for link erro
^~~~~~~~~~~~~~~~
p298a.cpp:16:14: error: 'initializer_list' is not a member of 'std'
p298a.cpp:16:42: error: expected primary-expression before '>' token
void f2(std::initializer_list<std::string>){}; // #4 U /// add {} for link erro
^
p298a.cpp:16:43: error: expected primary-expression before ')' token
void f2(std::initializer_list<std::string>){}; // #4 U /// add {} for link erro
^
p298a.cpp: In function 'void N::g2()':
p298a.cpp:17:16: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
void g2() { f2({"foo","bar"}); } // chooses #4
^
p298a.cpp: At global scope:
p298a.cpp:22:4: error: expected unqualified-id before '&&' token
int&& ia =0;
^~
p298a.cpp:24:4: error: expected unqualified-id before '&&' token
int&& f2(){return (int &&)ia;};/// add {} for link error
^~
p298a.cpp:26:16: error: expected ',' or '...' before '&&' token
int g(const int&&){return false;};/// add {} for link error
^~
p298a.cpp:27:12: error: call of overloaded 'g(int&)' is ambiguous
int j = g(i); // calls g(const int&)
^
p298a.cpp:25:5: note: candidate: 'int M::g(const int&)'
int g(const int&){return true;};/// add {} for link error
^
p298a.cpp:26:5: note: candidate: 'int M::g(int)'
int g(const int&&){return false;};/// add {} for link error
^
p298a.cpp:28:15: error: call of overloaded 'g(int)' is ambiguous
int k = g(f1()); // calls g(const int&&)
^
p298a.cpp:25:5: note: candidate: 'int M::g(const int&)'
int g(const int&){return true;};/// add {} for link error
^
p298a.cpp:26:5: note: candidate: 'int M::g(int)'
int g(const int&&){return false;};/// add {} for link error
^
p298a.cpp:29:11: error: 'f2' was not declared in this scope
int l = g(f2()); // calls g(const int&&)
^~
p298a.cpp:29:11: note: suggested alternative:
p298a.cpp:15:6: note: 'N::f2'
void f2(std::pair<const char*, const char*>){}; // #3 /// add {} for link error
^~
p298a.cpp:32:8: error: expected ';' at end of member declaration
void p() &{};/// add {} for link error
^
;
p298a.cpp:32:11: error: expected unqualified-id before '{' token
void p() &{};/// add {} for link error
^
p298a.cpp:33:8: error: expected ';' at end of member declaration
void p() &&{};/// add {} for link error
^
;
p298a.cpp:33:6: error: 'void M::A::p()' cannot be overloaded with 'void M::A::p()'
void p() &&{};/// add {} for link error
^
p298a.cpp:32:6: note: previous declaration 'void M::A::p()'
void p() &{};/// add {} for link error
^
p298a.cpp:33:10: error: expected unqualified-id before '&&' token
void p() &&{};/// add {} for link error
^~
p298a.cpp: In member function 'M::A& M::A::operator<<(int)':
p298a.cpp:31:20: warning: no return statement in function returning non-void [-Wreturn-type]
A& operator<<(int){};/// add {} for link error
^
p298a.cpp: At global scope:
p298a.cpp:35:16: error: expected ',' or '...' before '&&' token
A& operator<<(A&&, char){};/// add {} for link error
^~
p298a.cpp:35:24: error: 'M::A& M::operator<<(M::A)' must have exactly two arguments
A& operator<<(A&&, char){};/// add {} for link error
^
p298a.cpp:50:11: error: 'int P::f' redeclared as different kind of symbol
int f(void(&&)()); // #2
^
p298a.cpp:49:5: note: previous declaration 'int P::f(void (&)())'
int f(void(&)()){return true;}; // #1 /// add {} for link error
^
p298a.cpp:50:7: error: expected primary-expression before 'void'
int f(void(&&)()); // #2
^~~~
p298a.cpp: In member function 'S::A::operator short int()':
p298a.cpp:82:18: warning: no return statement in function returning non-void [-Wreturn-type]
operator short(){};/// add {} for link error
^
$ g++-8 p298a.cpp -std=c++2a -Wall
p298a.cpp: In member function 'M::A& M::A::operator<<(int)':
p298a.cpp:31:20: warning: no return statement in function returning non-void [-Wreturn-type]
A& operator<<(int){};/// add {} for link error
^
p298a.cpp: In function 'M::A& M::operator<<(M::A&&, char)':
p298a.cpp:35:26: warning: no return statement in function returning non-void [-Wreturn-type]
A& operator<<(A&&, char){};/// add {} for link error
^
p298a.cpp: In member function 'S::A::operator short int()':
p298a.cpp:82:18: warning: no return statement in function returning non-void [-Wreturn-type]
operator short(){};/// add {} for link error
^
C++N4741(173)16.3.3.2 Ranking implicit conversion sequences [over.ics.rank]p298a.cpp
#検討事項(agenda)
役に立つまたは意味のある警告の取り方
役に立つまたは意味のある他の出力
#参考資料(reference)
docker gnu(gcc/g++) and llvm(clang/clang++)
https://qiita.com/drafts/059874ea39c4de64c0f7
[C][C++]の国際規格案の例題をコンパイルするときの課題7つ。
https://qiita.com/kaizen_nagoya/items/5f4b155030259497c4de
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
Clang/Clang++(LLVM) gcc/g++(GNU) コンパイラ警告等比較
https://qiita.com/kaizen_nagoya/items/9a82b958cc3aeef0403f
C++2003とC++2017でコンパイルエラーになるならない事例集
https://qiita.com/kaizen_nagoya/items/a13ea3823441c430edff
Qiitaに投稿するCのStyle例(暫定)
https://qiita.com/kaizen_nagoya/items/946df1528a6a1ef2bc0d
cpprefjpのdecltypeをコンパイル試験
https://qiita.com/kaizen_nagoya/items/090909af702f0d5d8a67
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
#文書履歴(document history)
ver. 0.10 初稿 20180602