#はじめに
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
n4606は、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)まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。
list
N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(1) coding list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/
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.
#(98) 8.3.6 Default arguments [dcl.fct.default]
p212
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
#define msg "p212.cpp(98) 8.3.6 Default arguments [dcl.fct.default]"
#include <iostream>
void point(int = 3, int = 4);
point(1,2); point(1); point();
void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow
// a parameter with a default argument
void f(int, int);
void f(int, int = 7);
void h() {
f(3); // OK, calls f(3, 7)
void f(int = 1, int); // error: does not use default
// from surrounding scope
}
void m() {
void f(int, int); // has no defaults
f(4); // error: wrong number of arguments
void f(int, int = 5); // OK
f(4); // OK, calls f(4, 5);
void f(int, int = 5); // error: cannot redefine, even to
// same value
}
void n() {
f(6); // OK, calls f(6, 7)
}
int a = 1;
int f(int);
int g(int x = f(a)); // default argument: f(::a)
void h() {
a = 2;
{
int a = 3;
g(); // g(f(::a))
}
}
class C {
void f(int i = 3);
void g(int i, int j = 99);
};
void C::f(int i = 3) { // error: default argument already
} // specified in class scope
void C::g(int i = 88, int j) { // in this translation unit,
} // C::
void f() {
int i;
extern void g(int x = i); // error
extern void h(int x = sizeof(i)); // OK
// ...
}
class A {
void f(A* p = this) { } // error
};
int a;
int f(int a, int b = a); // error: parameter a
// used as default argument
typedef int I;
int g(float I, int b = I(2)); // error: parameter I found
int h(int a, int b = sizeof(a)); // OK, unevaluated operand
int b;
class X {
int a;
int mem1(int i = a); // error: non-static member a
// used as default argument
int mem2(int i = b); // OK; use X::b
static int b;
};
int f(int = 0);
void h() {
int j = f(1);
int k = f(); // OK, means f(0)
}
int (*p1)(int) = &f;
int (*p2)() = &f; // error: type mismatch
struct A {
virtual void f(int a = 7);
};
struct B : public A {
void f(int a);
};
void m() {
B* pb = new B;
A* pa = pb;
pa->f(); // OK, calls pa->B::f(7)
pb->f(); // error: wrong number of arguments for B::f()
}
int main(){
m();
std::cout<< msg << std::endl;
return EXIT_SUCCESS;
}
$ ./cppgl17.sh p212
$ clang++ p212.cpp
p212.cpp:9:1: error: C++ requires a type specifier for all declarations
point(1,2); point(1); point();
^
p212.cpp:9:13: error: C++ requires a type specifier for all declarations
point(1,2); point(1); point();
^
p212.cpp:9:23: error: C++ requires a type specifier for all declarations
point(1,2); point(1); point();
^
p212.cpp:17:22: error: missing default argument on parameter
void f(int = 1, int); // error: does not use default
^
p212.cpp:22:3: error: too few arguments to function call, expected 2, have 1; did you mean '::f'?
f(4); // error: wrong number of arguments
^
::f
p212.cpp:14:6: note: '::f' declared here
void f(int, int = 7);
^
p212.cpp:25:19: error: redefinition of default argument
void f(int, int = 5); // error: cannot redefine, even to
^ ~
p212.cpp:23:19: note: previous definition is here
void f(int, int = 5); // OK
^ ~
p212.cpp:34:15: error: call to 'f' is ambiguous
int g(int x = f(a)); // default argument: f(::a)
^
p212.cpp:14:6: note: candidate function
void f(int, int = 7);
^
p212.cpp:33:5: note: candidate function
int f(int);
^
p212.cpp:35:6: error: redefinition of 'h'
void h() {
^
p212.cpp:15:6: note: previous definition is here
void h() {
^
p212.cpp:47:15: error: redefinition of default argument
void C::f(int i = 3) { // error: default argument already
^ ~
p212.cpp:44:14: note: previous definition is here
void f(int i = 3);
^ ~
p212.cpp:54:25: error: default argument references local variable 'i' of enclosing function
extern void g(int x = i); // error
^
p212.cpp:55:32: error: default argument references local variable 'i' of enclosing function
extern void h(int x = sizeof(i)); // OK
~~~~~~~^~
p212.cpp:60:17: error: invalid use of 'this' outside of a non-static member function
void f(A* p = this) { } // error
^
p212.cpp:63:5: error: redefinition of 'a'
int a;
^
p212.cpp:32:5: note: previous definition is here
int a = 1;
^
p212.cpp:64:22: error: default argument references parameter 'a'
int f(int a, int b = a); // error: parameter a
^
p212.cpp:67:25: error: called object type 'float' is not a function or function pointer
int g(float I, int b = I(2)); // error: parameter I found
~^
p212.cpp:68:29: error: default argument references parameter 'a'
int h(int a, int b = sizeof(a)); // OK, unevaluated operand
~~~~~~~^~
p212.cpp:72:20: error: invalid use of non-static data member 'a'
int mem1(int i = a); // error: non-static member a
^
p212.cpp:80:11: error: call to 'f' is ambiguous
int j = f(1);
^
p212.cpp:14:6: note: candidate function
void f(int, int = 7);
^
p212.cpp:78:5: note: candidate function
int f(int = 0);
^
p212.cpp:81:11: error: call to 'f' is ambiguous
int k = f(); // OK, means f(0)
^
p212.cpp:52:6: note: candidate function
void f() {
^
p212.cpp:78:5: note: candidate function
int f(int = 0);
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
$ g++-7 p212.cpp
p212.cpp:9:6: error: expected constructor, destructor, or type conversion before '(' token
point(1,2); point(1); point();
^
p212.cpp:9:18: error: expected constructor, destructor, or type conversion before '(' token
point(1,2); point(1); point();
^
p212.cpp:9:30: error: expected constructor, destructor, or type conversion before ';' token
point(1,2); point(1); point();
^
p212.cpp: In function 'void h()':
p212.cpp:17:8: error: default argument missing for parameter 2 of 'void f(int, int)'
void f(int = 1, int); // error: does not use default
^
p212.cpp: In function 'void m()':
p212.cpp:22:6: error: too few arguments to function 'void f(int, int)'
f(4); // error: wrong number of arguments
^
p212.cpp:21:8: note: declared here
void f(int, int); // has no defaults
^
p212.cpp:25:22: error: default argument given for parameter 2 of 'void f(int, int)' [-fpermissive]
void f(int, int = 5); // error: cannot redefine, even to
^
p212.cpp:23:8: note: previous specification in 'void f(int, int)' here
void f(int, int = 5); // OK
^
p212.cpp: At global scope:
p212.cpp:34:18: error: call of overloaded 'f(int&)' is ambiguous
int g(int x = f(a)); // default argument: f(::a)
^
p212.cpp:14:6: note: candidate: void f(int, int)
void f(int, int = 7);
^
p212.cpp:33:5: note: candidate: int f(int)
int f(int);
^
p212.cpp: In function 'void h()':
p212.cpp:35:6: error: redefinition of 'void h()'
void h() {
^
p212.cpp:15:6: note: 'void h()' previously defined here
void h() {
^
p212.cpp:39:7: error: call of overloaded 'g()' is ambiguous
g(); // g(f(::a))
^
p212.cpp:11:6: note: candidate: void g(int, ...)
void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow
^
p212.cpp:34:5: note: candidate: int g(int)
int g(int x = f(a)); // default argument: f(::a)
^
p212.cpp: At global scope:
p212.cpp:47:20: error: default argument given for parameter 1 of 'void C::f(int)' [-fpermissive]
void C::f(int i = 3) { // error: default argument already
^
p212.cpp:44:8: note: previous specification in 'void C::f(int)' here
void f(int i = 3);
^
p212.cpp: In function 'void f()':
p212.cpp:54:25: error: local variable 'i' may not appear in this context
extern void g(int x = i); // error
^
p212.cpp:55:32: error: local variable 'i' may not appear in this context
extern void h(int x = sizeof(i)); // OK
^
p212.cpp: At global scope:
p212.cpp:60:17: error: 'this' may not be used in this context
void f(A* p = this) { } // error
^~~~
p212.cpp:63:5: error: redefinition of 'int a'
int a;
^
p212.cpp:32:5: note: 'int a' previously defined here
int a = 1;
^
p212.cpp:64:22: error: local variable 'a' may not appear in this context
int f(int a, int b = a); // error: parameter a
^
p212.cpp:64:5: error: ambiguating new declaration of 'int f(int, int)'
int f(int a, int b = a); // error: parameter a
^
p212.cpp:14:6: note: old declaration 'void f(int, int)'
void f(int, int = 7);
^
p212.cpp:67:24: error: local variable 'I' may not appear in this context
int g(float I, int b = I(2)); // error: parameter I found
^
p212.cpp:68:29: error: local variable 'a' may not appear in this context
int h(int a, int b = sizeof(a)); // OK, unevaluated operand
^
p212.cpp:72:20: error: invalid use of non-static data member 'X::a'
int mem1(int i = a); // error: non-static member a
^
p212.cpp:71:7: note: declared here
int a;
^
p212.cpp: In function 'void h()':
p212.cpp:79:6: error: redefinition of 'void h()'
void h() {
^
p212.cpp:15:6: note: 'void h()' previously defined here
void h() {
^
p212.cpp:80:14: error: call of overloaded 'f(int)' is ambiguous
int j = f(1);
^
p212.cpp:14:6: note: candidate: void f(int, int)
void f(int, int = 7);
^
p212.cpp:78:5: note: candidate: int f(int)
int f(int = 0);
^
p212.cpp:81:13: error: call of overloaded 'f()' is ambiguous
int k = f(); // OK, means f(0)
^
p212.cpp:78:5: note: candidate: int f(int)
int f(int = 0);
^
p212.cpp:52:6: note: candidate: void f()
void f() {
^
p212.cpp: At global scope:
p212.cpp:84:16: error: no matches converting function 'f' to type 'int (*)()'
int (*p2)() = &f; // error: type mismatch
^
p212.cpp:52:6: note: candidates are: void f()
void f() {
^
p212.cpp:78:5: note: int f(int)
int f(int = 0);
^
p212.cpp:14:6: note: void f(int, int)
void f(int, int = 7);
^
p212.cpp:86:8: error: redefinition of 'struct A'
struct A {
^
p212.cpp:59:7: note: previous definition of 'struct A'
class A {
^
p212.cpp: In function 'void m()':
p212.cpp:92:6: error: redefinition of 'void m()'
void m() {
^
p212.cpp:20:6: note: 'void m()' previously defined here
void m() {
^
p212.cpp:95:9: error: 'void A::f(A*)' is private within this context
pa->f(); // OK, calls pa->B::f(7)
^
p212.cpp:60:8: note: declared private here
void f(A* p = this) { } // error
^
p212.cpp:95:9: error: call to 'void A::f(A*)' uses the default argument for parameter 1, which is not yet defined
pa->f(); // OK, calls pa->B::f(7)
^
p212.cpp:96:9: error: no matching function for call to 'B::f()'
pb->f(); // error: wrong number of arguments for B::f()
^
p212.cpp:90:8: note: candidate: void B::f(int)
void f(int a);
^
p212.cpp:90:8: note: candidate expects 1 argument, 0 provided
#検討事項
今回、たまたまg++が実行時エラーになったのかどうかの確認。
g++の実行時エラーを修正する方法。
#参考資料
コンパイル用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++完全理解ガイド」の同意できること上位7
https://qiita.com/kaizen_nagoya/items/aa5744e0c4a8618c7671
#文書履歴
0.10 初稿 2080417