0
0

More than 1 year has passed since last update.

7.5.5.3 Captures [expr.prim.lambda.capture] C++N4910:2022 (46) p109.cpp

Posted at

はじめに(Introduction)

N4910 Working Draft, Standard for Programming Language C++

n4910は、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)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。

<この項は書きかけです。順次追記します。>

背景(back ground)

C/C++でコンパイルエラーが出ると、途方にくれることがしばしばあります。
何回かに1回は、該当するエラーが検索できます。
ただ、条件が違っていて、そこでの修正方法では目的を達成しないこともしばしばです。いろいろな条件のコンパイルエラーとその対応方法について、広く記録することによって、いつか同じエラーに遭遇した時にやくに立つことを目指しています。

この半年の間で、三度、自分のネットでの記録に助けられたことがあります。
また過去に解決できなかった記録を10種類以上、最近になって解決できたことがあります。それは、主に次の3つの情報に基づいています。

https://stackoverflow.com
https://cpprefjp.github.io
http://ja.cppreference.com/

また
https://researchmap.jp/joub9b3my-1797580/#_1797580
に記載したサイトのお世話になっています。

作業方針(sequence)

Clang++では-std=c++03, C++2bの2種類
g++では-std=c++03, c++2bの2種類
でコンパイルし、

1)コンパイルエラーを収集する。
2)コンパイルエラーをなくす方法を検討する。
コンパイルエラーになる例を示すだけが目的のコードは、コンパイルエラーをなくすのではなく、コンパイルエラーの種類を収集するだけにする。
文法を示すのが目的のコード場合に、コンパイルエラーをなくすのに手間がかかる場合は、順次作業します。
3)リンクエラーをなくす方法を検討する。
文法を示すのが目的のコード場合に、リンクエラーをなくすのに手間がかかる場合は、順次作業します。
4)意味のある出力を作る。
コンパイル、リンクが通っても、意味のある出力を示そうとすると、コンパイル・リンクエラーが出て収拾できそうにない場合がある。順次作業します。

1)だけのものから4)まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。

C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list

C++N4741, 2018 Standard Working Draft on ISO/IEC 14882 sample code compile list

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++

編纂器(Compiler)

clang++ --version

Debian clang version 14.0.5-++20220610033153+c12386ae247c-1~exp1~20220610153237.151
Target: x86_64-pc-linux-gnu, Thread model: posix, InstalledDir: /usr/bin

g++- --version

g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

7.5.5.3 Captures [expr.prim.lambda.capture] C++N4910:2022 (46) p109.cpp

算譜(source code)

p109.cpp
// C++N4910 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf
const char * msg="7.5.5.3 Captures [expr.prim.lambda.capture] C++N4910:2022 (46) p109.cpp";
// Debian clang version 14.0.5-++20220610033153+c12386ae247c-
// g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
// Edited by Dr. Ogawa Kiyoshi. Compile procedure and results record.
// C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
// https://qiita.com/kaizen_nagoya/items/fc957ddddd402004bb91

#include <iostream>
#include <cstdlib> 
#include <cstring>

using namespace std;

// Example 1
struct S2 { void f(int i); };
void S2::f(int i) {
[&, i]{ }; // OK
[&, this, i]{ }; // OK, equivalent to [&, i]
[&, &i]{ }; // error: i preceded by & when & is the default
[=, *this]{ }; // OK
[=, this]{ }; // OK, equivalent to [=]
[i, i]{ }; // error: i repeated
[this, *this]{ }; // error: this appears twice
}
// [Example 2 :
void f() {
int x = 0;
auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
}
// [Example 3 :
int x = 4;
auto y = [&r = x, x = x+1]()->int {
r += 2;
return x+2;
}(); // Updates ::x to 6, and initializes y to 7.
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
return i++;
};
// [Example 4 :
void f(int, const int (&)[2] = {}); // #1
void f(const int&, const int (&)[1]); // #2
void test() {
const int x = 17;
auto g = [](auto a) {
f(x); // OK, calls #1, does not capture x
};
auto g1 = [=](auto a) {
f(x); // OK, calls #1, captures x
};
auto g2 = [=](auto a) {
int selector[sizeof(a) == 1 ? 1 : 2]{};
f(x, selector); // OK, captures x, can call #1 or #2
};
auto g3 = [=](auto a) {
typeid(a + x); // captures x regardless of whether a + x is an unevaluated operand
};
}
// Within g1, an implementation can optimize away the capture of x as it is not odr-used.
// [Example 5 :
template<bool B>
void f(int n) {
[=](auto a) {
if constexpr (B && sizeof(a) > 4) {
(void)n; // captures n regardless of the value of B and sizeof(int)
}
}(0);
}
// [Example 6 :
void f1(int i) {
int const N = 20;
auto m1 = [=]{
int const M = 30;
auto m2 = [i]{
int x[N][M]; // OK, N and M are not odr-used
x[0][0] = i; // OK, i is explicitly captured by m2 and implicitly captured by m1
};
};
struct s1 {
int f;
void work(int n) {
int m = n*n;
int j = 40;
auto m3 = [this,m] {
auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3
int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3
x += m; // OK, m implicitly captured by m4 and explicitly captured by m3
x += i; // error: i is odr-used but not odr-usable
// due to intervening function and class scopes
x += f; // OK, this captured implicitly by m4 and explicitly by m3
};
};
}
};
}
struct s2 {
double ohseven = .007;
auto f() {
return [this] {
return [*this] {
return ohseven; // OK
};
}();
}
auto g() {
return [] {
return [*this] { }; // error: *this not captured by outer lambda-expression
}();
}
};
// [Example 7 :
void f2() {
int i = 1;
void g1(int = ([i]{ return i; })()); // error
void g2(int = ([i]{ return 0; })()); // error
void g3(int = ([=]{ return i; })()); // error
void g4(int = ([=]{ return 0; })()); // OK
void g5(int = ([]{ return sizeof i; })()); // OK
void g6(int = ([x=1]{ return x; })()); // OK
void g7(int = ([x=i]{ return x; })()); // error
}
// [Example 8 :
void f(const int*);
void g() {
const int N = 10;
[=] {
int arr[N]; // OK, not an odr-use, refers to automatic variable
f(&N); // OK, causes N to be captured; &N points to
// the corresponding member of the closure type
};
}
// [Example 9 :
// The inner closure type must be a literal type regardless of how reference captures are represented.
static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
// [Example 10 :
auto h(int &r) {
return [&] {
++r; // Valid after h returns if the lifetime of the
// object to which r is bound has not ended
};
}
// [Example 12 :
template<class... Args>
void f(Args... args) {
auto lm = [&, args...] { return g(args...); };
lm();
auto lm2 = [...xs=std::move(args)] { return g(xs...); };
lm2();
}
int main() {
// [Example 11 : The nested lambda-expressions and invocations below will output 123234.
int a = 1, b = 1, c = 1;
auto m1 = [a, &b, &c]() mutable {
auto m2 = [a, b, &c]() mutable {
std::cout << a << b << c;
a = 4; b = 4; c = 4;
};
a = 3; b = 3; c = 3;
m2();
};
a = 2; b = 2; c = 2;
m1();
std::cout << a << b << c;
// int main (){
  cout  <<  msg << endl;
  return EXIT_SUCCESS;
}

Script

clgc.sh
#!/bin/sh
rm $1l
rm $1g
echo "$ clang++ $1.cpp -std=03 -o $1l -I. -Wall" 
clang++ $1.cpp -std=c++03 -o $1l -I. -Wall
if [  -e $1l ]; then
./$1l 
fi
rm $1l
echo "$ clang++ $1.cpp -std=2b -o $1l -I. -Wall"
clang++ $1.cpp -std=c++2b -o $1l -I. -Wall
if [  -e $1l ]; then
./$1l
fi
echo "\r"
echo "$ g++ $1.cpp -std=03 -o $1g -I. -Wall"
g++ $1.cpp -std=c++03 -o $1g -I. -Wall
if [ -e $1g ]; then
./$1g
fi
rm $1g
echo "\r"
echo "$ g++ $1.cpp -std=2b -o $1g -I. -Wall"
g++ $1.cpp -std=c++2b -o $1g -I. -Wall
if [ -e $1g ]; then
./$1g 
fi

編纂・実行結果(compile and go)

bash
# ./clgc.sh  p109
rm: cannot remove 'p109l': No such file or directory
rm: cannot remove 'p109g': No such file or directory
$ clang++ p109.cpp -std=03 -o p109l -I. -Wall
p109.cpp:19:1: error: expected expression
[&, i]{ }; // OK
^
p109.cpp:20:1: error: expected expression
[&, this, i]{ }; // OK, equivalent to [&, i]
^
p109.cpp:21:1: error: expected expression
[&, &i]{ }; // error: i preceded by & when & is the default
^
p109.cpp:22:1: error: expected expression
[=, *this]{ }; // OK
^
p109.cpp:23:1: error: expected expression
[=, this]{ }; // OK, equivalent to [=]
^
p109.cpp:24:1: error: expected expression
[i, i]{ }; // error: i repeated
^
p109.cpp:25:1: error: expected expression
[this, *this]{ }; // error: this appears twice
^
p109.cpp:30:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
^
p109.cpp:30:10: error: expected expression
auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
         ^
p109.cpp:34:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto y = [&r = x, x = x+1]()->int {
^
p109.cpp:34:10: error: expected expression
auto y = [&r = x, x = x+1]()->int {
         ^
p109.cpp:38:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
^
p109.cpp:38:10: error: expected expression
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
         ^
p109.cpp:39:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
^
p109.cpp:39:16: error: expected expression
auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
               ^
p109.cpp:43:32: error: expected expression
void f(int, const int (&)[2] = {}); // #1
                               ^
p109.cpp:47:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto g = [](auto a) {
^
p109.cpp:47:10: error: expected expression
auto g = [](auto a) {
         ^
p109.cpp:50:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto g1 = [=](auto a) {
^
p109.cpp:50:11: error: expected expression
auto g1 = [=](auto a) {
          ^
p109.cpp:53:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto g2 = [=](auto a) {
^
p109.cpp:53:11: error: expected expression
auto g2 = [=](auto a) {
          ^
p109.cpp:57:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto g3 = [=](auto a) {
^
p109.cpp:57:11: error: expected expression
auto g3 = [=](auto a) {
          ^
p109.cpp:65:1: error: expected expression
[=](auto a) {
^
p109.cpp:74:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto m1 = [=]{
^
p109.cpp:74:11: error: expected expression
auto m1 = [=]{
          ^
p109.cpp:86:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto m3 = [this,m] {
^
p109.cpp:86:11: error: expected expression
auto m3 = [this,m] {
          ^
p109.cpp:99:16: warning: default member initializer for non-static data member is a C++11 extension [-Wc++11-extensions]
double ohseven = .007;
               ^
p109.cpp:100:1: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto f() {
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
12 warnings and 20 errors generated.
rm: cannot remove 'p109l': No such file or directory
$ clang++ p109.cpp -std=2b -o p109l -I. -Wall
p109.cpp:19:5: warning: lambda capture 'i' is not used [-Wunused-lambda-capture]
[&, i]{ }; // OK
  ~~^
p109.cpp:20:5: warning: lambda capture 'this' is not used [-Wunused-lambda-capture]
[&, this, i]{ }; // OK, equivalent to [&, i]
  ~~^~~~
p109.cpp:20:11: warning: lambda capture 'i' is not used [-Wunused-lambda-capture]
[&, this, i]{ }; // OK, equivalent to [&, i]
        ~~^
p109.cpp:21:6: error: '&' cannot precede a capture when the capture default is '&'
[&, &i]{ }; // error: i preceded by & when & is the default
  ~~~^
p109.cpp:22:5: warning: lambda capture 'this' is not used [-Wunused-lambda-capture]
[=, *this]{ }; // OK
  ~~^~~~~
p109.cpp:23:5: warning: lambda capture 'this' is not used [-Wunused-lambda-capture]
[=, this]{ }; // OK, equivalent to [=]
  ~~^~~~
p109.cpp:24:5: error: 'i' can appear only once in a capture list
[i, i]{ }; // error: i repeated
 ~~~^
p109.cpp:24:2: warning: lambda capture 'i' is not used [-Wunused-lambda-capture]
[i, i]{ }; // error: i repeated
 ^
p109.cpp:25:8: error: 'this' can appear only once in a capture list
[this, *this]{ }; // error: this appears twice
 ~~~~~~^
      
p109.cpp:25:2: warning: lambda capture 'this' is not used [-Wunused-lambda-capture]
[this, *this]{ }; // error: this appears twice
 ^~~~
p109.cpp:19:1: warning: expression result unused [-Wunused-value]
[&, i]{ }; // OK
^~~~~~~~~
p109.cpp:20:1: warning: expression result unused [-Wunused-value]
[&, this, i]{ }; // OK, equivalent to [&, i]
^~~~~~~~~~~~~~~
p109.cpp:21:1: warning: expression result unused [-Wunused-value]
[&, &i]{ }; // error: i preceded by & when & is the default
^~~~~~~~~~
p109.cpp:22:1: warning: expression result unused [-Wunused-value]
[=, *this]{ }; // OK
^~~~~~~~~~~~~
p109.cpp:23:1: warning: expression result unused [-Wunused-value]
[=, this]{ }; // OK, equivalent to [=]
^~~~~~~~~~~~
p109.cpp:24:1: warning: expression result unused [-Wunused-value]
[i, i]{ }; // error: i repeated
^~~~~~~~~
p109.cpp:25:1: warning: expression result unused [-Wunused-value]
[this, *this]{ }; // error: this appears twice
^~~~~~~~~~~~~~~~
p109.cpp:30:18: error: a lambda parameter cannot shadow an explicitly captured entity
auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
                 ^
p109.cpp:30:11: note: variable 'x' is explicitly captured here
auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
          ^
p109.cpp:30:11: warning: lambda capture 'x' is not used [-Wunused-lambda-capture]
auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
          ^
p109.cpp:38:23: error: a lambda parameter cannot shadow an explicitly captured entity
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
                      ^
p109.cpp:38:11: note: variable 'a' is explicitly captured here
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
          ^
p109.cpp:38:11: warning: lambda capture 'a' is not used [-Wunused-lambda-capture]
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
          ^~~~~~
p109.cpp:39:44: error: use of undeclared identifier 'i'
auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
                                           ^
p109.cpp:58:1: warning: expression result unused [-Wunused-value]
typeid(a + x); // captures x regardless of whether a + x is an unevaluated operand
^~~~~~~~~~~~~
p109.cpp:53:6: warning: unused variable 'g2' [-Wunused-variable]
auto g2 = [=](auto a) {
     ^
p109.cpp:47:6: warning: unused variable 'g' [-Wunused-variable]
auto g = [](auto a) {
     ^
p109.cpp:50:6: warning: unused variable 'g1' [-Wunused-variable]
auto g1 = [=](auto a) {
     ^
p109.cpp:57:6: warning: unused variable 'g3' [-Wunused-variable]
auto g3 = [=](auto a) {
     ^
p109.cpp:76:6: warning: unused variable 'm2' [-Wunused-variable]
auto m2 = [i]{
     ^
p109.cpp:87:14: error: variable 'j' cannot be implicitly captured in a lambda with no capture-default specified
auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3
             ^
p109.cpp:85:5: note: 'j' declared here
int j = 40;
    ^
p109.cpp:86:11: note: lambda expression begins here
auto m3 = [this,m] {
          ^
p109.cpp:86:18: note: capture 'j' by value
auto m3 = [this,m] {
                 ^
                 , j
p109.cpp:86:18: note: capture 'j' by reference
auto m3 = [this,m] {
                 ^
                 , &j
p109.cpp:88:9: error: variable 'n' cannot be implicitly captured in a lambda with no capture-default specified
int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3
        ^
p109.cpp:83:15: note: 'n' declared here
void work(int n) {
              ^
p109.cpp:86:11: note: lambda expression begins here
auto m3 = [this,m] {
          ^
p109.cpp:86:18: note: capture 'n' by value
auto m3 = [this,m] {
                 ^
                 , n
p109.cpp:86:18: note: capture 'n' by reference
auto m3 = [this,m] {
                 ^
                 , &n
p109.cpp:90:6: error: variable 'i' cannot be implicitly captured in a lambda with no capture-default specified
x += i; // error: i is odr-used but not odr-usable
     ^
p109.cpp:72:13: note: 'i' declared here
void f1(int i) {
            ^
p109.cpp:86:11: note: lambda expression begins here
auto m3 = [this,m] {
          ^
p109.cpp:86:18: note: capture 'i' by value
auto m3 = [this,m] {
                 ^
                 , i
p109.cpp:86:18: note: capture 'i' by reference
auto m3 = [this,m] {
                 ^
                 , &i
p109.cpp:109:9: error: 'this' cannot be implicitly captured in this context
return [*this] { }; // error: *this not captured by outer lambda-expression
        ^
p109.cpp:116:16: error: lambda expression in default argument cannot capture any entity
void g1(int = ([i]{ return i; })()); // error
               ^
p109.cpp:117:17: warning: lambda capture 'i' is not used [-Wunused-lambda-capture]
void g2(int = ([i]{ return 0; })()); // error
                ^
p109.cpp:117:16: error: lambda expression in default argument cannot capture any entity
void g2(int = ([i]{ return 0; })()); // error
               ^
p109.cpp:118:16: error: lambda expression in default argument cannot capture any entity
void g3(int = ([=]{ return i; })()); // error
               ^
p109.cpp:121:16: error: lambda expression in default argument cannot capture any entity
void g6(int = ([x=1]{ return x; })()); // OK
               ^
p109.cpp:122:16: error: lambda expression in default argument cannot capture any entity
void g7(int = ([x=i]{ return x; })()); // error
               ^
p109.cpp:129:5: warning: unused variable 'arr' [-Wunused-variable]
int arr[N]; // OK, not an odr-use, refers to automatic variable
    ^
p109.cpp:128:1: warning: expression result unused [-Wunused-value]
[=] {
^~~~~
25 warnings and 15 errors generated.

$ g++ p109.cpp -std=03 -o p109g -I. -Wall
p109.cpp:39:35: warning: identifier 'decltype' is a keyword in C++11 [-Wc++11-compat]
   39 | auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
      |                                   ^~~~~~~~
p109.cpp:66:4: warning: identifier 'constexpr' is a keyword in C++11 [-Wc++11-compat]
   66 | if constexpr (B && sizeof(a) > 4) {
      |    ^~~~~~~~~
p109.cpp:136:1: warning: identifier 'static_assert' is a keyword in C++11 [-Wc++11-compat]
  136 | static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
      | ^~~~~~~~~~~~~
p109.cpp: In member function 'void S2::f(int)':
p109.cpp:19:9: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   19 | [&, i]{ }; // OK
      |         ^
p109.cpp:20:15: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   20 | [&, this, i]{ }; // OK, equivalent to [&, i]
      |               ^
p109.cpp:21:6: warning: explicit by-reference capture of 'i' redundant with by-reference capture default
   21 | [&, &i]{ }; // error: i preceded by & when & is the default
      |      ^
p109.cpp:21:10: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   21 | [&, &i]{ }; // error: i preceded by & when & is the default
      |          ^
p109.cpp:22:5: warning: '*this' capture only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
   22 | [=, *this]{ }; // OK
      |     ^
p109.cpp:22:13: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   22 | [=, *this]{ }; // OK
      |             ^
p109.cpp:23:12: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   23 | [=, this]{ }; // OK, equivalent to [=]
      |            ^
p109.cpp:24:5: warning: already captured 'i' in lambda expression
   24 | [i, i]{ }; // error: i repeated
      |     ^
p109.cpp:24:9: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   24 | [i, i]{ }; // error: i repeated
      |         ^
p109.cpp:25:8: warning: '*this' capture only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
   25 | [this, *this]{ }; // error: this appears twice
      |        ^
p109.cpp:25:9: warning: already captured 'this' in lambda expression
   25 | [this, *this]{ }; // error: this appears twice
      |         ^~~~
p109.cpp:25:16: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   25 | [this, *this]{ }; // error: this appears twice
      |                ^
p109.cpp: In function 'void f()':
p109.cpp:30:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   30 | auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
      | ^~~~
      | ----
p109.cpp:30:6: error: 'g' does not name a type
   30 | auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
      |      ^
p109.cpp:29:5: warning: unused variable 'x' [-Wunused-variable]
   29 | int x = 0;
      |     ^
p109.cpp: At global scope:
p109.cpp:34:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   34 | auto y = [&r = x, x = x+1]()->int {
      | ^~~~
      | ----
p109.cpp:34:6: error: 'y' does not name a type
   34 | auto y = [&r = x, x = x+1]()->int {
      |      ^
p109.cpp:37:3: error: expected unqualified-id before ')' token
   37 | }(); // Updates ::x to 6, and initializes y to 7.
      |   ^
p109.cpp:38:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   38 | auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
      | ^~~~
      | ----
p109.cpp:38:6: error: 'z' does not name a type
   38 | auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
      |      ^
p109.cpp:39:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   39 | auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
      | ^~~~
      | ----
p109.cpp:39:6: error: 'counter' does not name a type
   39 | auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
      |      ^~~~~~~
p109.cpp:43:33: warning: extended initializer lists only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   43 | void f(int, const int (&)[2] = {}); // #1
      |                                 ^
p109.cpp:43:34: warning: extended initializer lists only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   43 | void f(int, const int (&)[2] = {}); // #1
      |                                  ^
p109.cpp: In function 'void test()':
p109.cpp:47:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   47 | auto g = [](auto a) {
      | ^~~~
      | ----
p109.cpp:47:6: error: 'g' does not name a type
   47 | auto g = [](auto a) {
      |      ^
p109.cpp:50:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   50 | auto g1 = [=](auto a) {
      | ^~~~
      | ----
p109.cpp:50:6: error: 'g1' does not name a type
   50 | auto g1 = [=](auto a) {
      |      ^~
p109.cpp:53:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   53 | auto g2 = [=](auto a) {
      | ^~~~
      | ----
p109.cpp:53:6: error: 'g2' does not name a type; did you mean 'S2'?
   53 | auto g2 = [=](auto a) {
      |      ^~
      |      S2
p109.cpp:57:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   57 | auto g3 = [=](auto a) {
      | ^~~~
      | ----
p109.cpp:57:6: error: 'g3' does not name a type
   57 | auto g3 = [=](auto a) {
      |      ^~
p109.cpp:46:11: warning: unused variable 'x' [-Wunused-variable]
   46 | const int x = 17;
      |           ^
p109.cpp: In function 'void f(int)':
p109.cpp:65:5: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   65 | [=](auto a) {
      |     ^~~~
      |     ----
p109.cpp:65:10: error: 'a' does not name a type
   65 | [=](auto a) {
      |          ^
p109.cpp:69:3: error: expected ')' before numeric constant
   69 | }(0);
      |  ~^
      |   )
p109.cpp:69:3: error: expected ')' before numeric constant
   69 | }(0);
      |   ^
      |   )
p109.cpp:65:4: note: to match this '('
   65 | [=](auto a) {
      |    ^
p109.cpp: In lambda function:
p109.cpp:69:3: error: expected '{' before numeric constant
   69 | }(0);
      |   ^
p109.cpp: In function 'void f(int)':
p109.cpp:69:3: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
p109.cpp:69:3: error: expected ';' before numeric constant
   69 | }(0);
      |   ^
      |   ;
p109.cpp: In function 'void f1(int)':
p109.cpp:74:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   74 | auto m1 = [=]{
      | ^~~~
      | ----
p109.cpp:74:6: error: 'm1' does not name a type
   74 | auto m1 = [=]{
      |      ^~
p109.cpp: In member function 'void f1(int)::s1::work(int)':
p109.cpp:86:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
   86 | auto m3 = [this,m] {
      | ^~~~
      | ----
p109.cpp:86:6: error: 'm3' does not name a type
   86 | auto m3 = [this,m] {
      |      ^~
p109.cpp:84:5: warning: unused variable 'm' [-Wunused-variable]
   84 | int m = n*n;
      |     ^
p109.cpp:85:5: warning: unused variable 'j' [-Wunused-variable]
   85 | int j = 40;
      |     ^
p109.cpp: In function 'void f1(int)':
p109.cpp:73:11: warning: unused variable 'N' [-Wunused-variable]
   73 | int const N = 20;
      |           ^
p109.cpp: At global scope:
p109.cpp:99:16: warning: non-static data member initializers only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   99 | double ohseven = .007;
      |                ^
p109.cpp:100:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
  100 | auto f() {
      | ^~~~
      | ----
p109.cpp:100:6: error: ISO C++ forbids declaration of 'f' with no type [-fpermissive]
  100 | auto f() {
      |      ^
p109.cpp:100:1: error: storage class specified for 'f'
  100 | auto f() {
      | ^~~~
p109.cpp:107:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
  107 | auto g() {
      | ^~~~
      | ----
p109.cpp:107:6: error: ISO C++ forbids declaration of 'g' with no type [-fpermissive]
  107 | auto g() {
      |      ^
p109.cpp:107:1: error: storage class specified for 'g'
  107 | auto g() {
      | ^~~~
p109.cpp: In lambda function:
p109.cpp:102:9: warning: '*this' capture only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
  102 | return [*this] {
      |         ^
p109.cpp:104:1: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  104 | };
      | ^
p109.cpp: In member function 'int s2::f()':
p109.cpp:105:1: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  105 | }();
      | ^
p109.cpp:105:2: error: cannot convert 's2::f()::<lambda()>::<lambda()>' to 'int' in return
  101 | return [this] {
      |        ~~~~~~~~
  102 | return [*this] {
      | ~~~~~~~~~~~~~~~~
  103 | return ohseven; // OK
      | ~~~~~~~~~~~~~~~~~~~~~
  104 | };
      | ~~
  105 | }();
      | ~^~
      |  |
      |  s2::f()::<lambda()>::<lambda()>
p109.cpp: In lambda function:
p109.cpp:109:9: warning: '*this' capture only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
  109 | return [*this] { }; // error: *this not captured by outer lambda-expression
      |         ^
p109.cpp:109:10: error: 'this' was not captured for this lambda function
  109 | return [*this] { }; // error: *this not captured by outer lambda-expression
      |          ^~~~
p109.cpp:109:18: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  109 | return [*this] { }; // error: *this not captured by outer lambda-expression
      |                  ^
p109.cpp: In member function 'int s2::g()':
p109.cpp:110:1: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  110 | }();
      | ^
p109.cpp:110:2: error: invalid user-defined conversion from 's2::g()::<lambda()>::<lambda()>' to 'int' [-fpermissive]
  108 | return [] {
      |        ~~~~
  109 | return [*this] { }; // error: *this not captured by outer lambda-expression
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  110 | }();
      | ~^~
p109.cpp:109:8: note: candidate is: 's2::g()::<lambda()>::<lambda()>::operator void (*)()() const' (near match)
  109 | return [*this] { }; // error: *this not captured by outer lambda-expression
      |        ^
p109.cpp:109:8: note:   no known conversion from 'void (*)()' to 'int'
p109.cpp: In function 'void f2()':
p109.cpp:116:31: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  116 | void g1(int = ([i]{ return i; })()); // error
      |                               ^
p109.cpp:116:35: error: default argument '<lambda closure object>f2()::<lambda()>{i}.f2()::<lambda()>()' uses local variable 'i'
  116 | void g1(int = ([i]{ return i; })()); // error
      |                                   ^
p109.cpp:117:31: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  117 | void g2(int = ([i]{ return 0; })()); // error
      |                               ^
p109.cpp:117:35: error: default argument '<lambda closure object>f2()::<lambda()>{i}.f2()::<lambda()>()' uses local variable 'i'
  117 | void g2(int = ([i]{ return 0; })()); // error
      |                                   ^
p109.cpp:118:31: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  118 | void g3(int = ([=]{ return i; })()); // error
      |                               ^
p109.cpp:118:35: error: default argument '<lambda closure object>f2()::<lambda()>{i}.f2()::<lambda()>()' uses local variable 'i'
  118 | void g3(int = ([=]{ return i; })()); // error
      |                                   ^
p109.cpp:119:31: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  119 | void g4(int = ([=]{ return 0; })()); // OK
      |                               ^
p109.cpp:120:37: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  120 | void g5(int = ([]{ return sizeof i; })()); // OK
      |                                     ^
p109.cpp:121:17: warning: lambda capture initializers only available with '-std=c++14' or '-std=gnu++14' [-Wc++14-extensions]
  121 | void g6(int = ([x=1]{ return x; })()); // OK
      |                 ^
p109.cpp:121:33: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  121 | void g6(int = ([x=1]{ return x; })()); // OK
      |                                 ^
p109.cpp:122:17: warning: lambda capture initializers only available with '-std=c++14' or '-std=gnu++14' [-Wc++14-extensions]
  122 | void g7(int = ([x=i]{ return x; })()); // error
      |                 ^
p109.cpp:122:19: error: local variable 'i' may not appear in this context
  122 | void g7(int = ([x=i]{ return x; })()); // error
      |                   ^
p109.cpp:122:33: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  122 | void g7(int = ([x=i]{ return x; })()); // error
      |                                 ^
p109.cpp: In lambda function:
p109.cpp:129:5: warning: unused variable 'arr' [-Wunused-variable]
  129 | int arr[N]; // OK, not an odr-use, refers to automatic variable
      |     ^~~
p109.cpp: In function 'void g()':
p109.cpp:132:1: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  132 | };
      | ^
p109.cpp: At global scope:
p109.cpp:136:14: error: expected constructor, destructor, or type conversion before '(' token
  136 | static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
      |              ^
p109.cpp:136:60: error: expected unqualified-id before numeric constant
  136 | static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
      |                                                            ^
p109.cpp:136:60: error: expected ')' before numeric constant
  136 | static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
      |                                                           ~^
      |                                                            )
p109.cpp:138:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
  138 | auto h(int &r) {
      | ^~~~
      | ----
p109.cpp:138:6: error: ISO C++ forbids declaration of 'h' with no type [-fpermissive]
  138 | auto h(int &r) {
      |      ^
p109.cpp:138:1: error: top-level declaration of 'h' specifies 'auto'
  138 | auto h(int &r) {
      | ^~~~
p109.cpp:138:1: error: storage class 'auto' invalid for function 'h'
p109.cpp: In function 'int h(int&)':
p109.cpp:142:1: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  142 | };
      | ^
p109.cpp:139:8: error: cannot convert 'h(int&)::<lambda()>' to 'int' in return
  139 | return [&] {
      |        ^~~~~
      |        |
      |        h(int&)::<lambda()>
  140 | ++r; // Valid after h returns if the lifetime of the
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  141 | // object to which r is bound has not ended
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  142 | };
      | ~       
p109.cpp: At global scope:
p109.cpp:145:15: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  145 | template<class... Args>
      |               ^~~
p109.cpp:146:16: warning: variadic templates only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
  146 | void f(Args... args) {
      |                ^~~~
p109.cpp: In function 'void f(Args ...)':
p109.cpp:147:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
  147 | auto lm = [&, args...] { return g(args...); };
      | ^~~~
      | ----
p109.cpp:147:6: error: 'lm' does not name a type; did you mean 'tm'?
  147 | auto lm = [&, args...] { return g(args...); };
      |      ^~
      |      tm
p109.cpp:148:1: error: there are no arguments to 'lm' that depend on a template parameter, so a declaration of 'lm' must be available [-fpermissive]
  148 | lm();
      | ^~
p109.cpp:148:1: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
p109.cpp:149:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
  149 | auto lm2 = [...xs=std::move(args)] { return g(xs...); };
      | ^~~~
      | ----
p109.cpp:149:6: error: 'lm2' does not name a type
  149 | auto lm2 = [...xs=std::move(args)] { return g(xs...); };
      |      ^~~
p109.cpp:150:1: error: there are no arguments to 'lm2' that depend on a template parameter, so a declaration of 'lm2' must be available [-fpermissive]
  150 | lm2();
      | ^~~
p109.cpp: In function 'int main()':
p109.cpp:155:1: warning: 'auto' changes meaning in C++11; please remove it [-Wc++11-compat]
  155 | auto m1 = [a, &b, &c]() mutable {
      | ^~~~
      | ----
p109.cpp:155:6: error: 'm1' does not name a type
  155 | auto m1 = [a, &b, &c]() mutable {
      |      ^~
p109.cpp:164:1: error: 'm1' was not declared in this scope; did you mean 'f1'?
  164 | m1();
      | ^~
      | f1
rm: cannot remove 'p109g': No such file or directory

$ g++ p109.cpp -std=2b -o p109g -I. -Wall
p109.cpp: In member function 'void S2::f(int)':
p109.cpp:21:6: warning: explicit by-reference capture of 'i' redundant with by-reference capture default
   21 | [&, &i]{ }; // error: i preceded by & when & is the default
      |      ^
p109.cpp:24:5: warning: already captured 'i' in lambda expression
   24 | [i, i]{ }; // error: i repeated
      |     ^
p109.cpp:25:9: warning: already captured 'this' in lambda expression
   25 | [this, *this]{ }; // error: this appears twice
      |         ^~~~
p109.cpp: In lambda function:
p109.cpp:30:18: error: lambda parameter 'x' previously declared as a capture
   30 | auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
      |              ~~~~^
p109.cpp: In lambda function:
p109.cpp:38:23: error: lambda parameter 'a' previously declared as a capture
   38 | auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
      |                   ~~~~^
p109.cpp: At global scope:
p109.cpp:39:44: error: 'i' was not declared in this scope
   39 | auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
      |                                            ^
p109.cpp:39:44: error: 'i' was not declared in this scope
p109.cpp: In lambda function:
p109.cpp:87:14: error: 'j' is not captured
   87 | auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3
      |              ^
p109.cpp:86:18: note: the lambda has no capture-default
   86 | auto m3 = [this,m] {
      |                  ^
p109.cpp:85:5: note: 'int j' declared here
   85 | int j = 40;
      |     ^
p109.cpp: In lambda function:
p109.cpp:88:9: error: 'n' is not captured
   88 | int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3
      |         ^
p109.cpp:86:18: note: the lambda has no capture-default
   86 | auto m3 = [this,m] {
      |                  ^
p109.cpp:83:15: note: 'int n' declared here
   83 | void work(int n) {
      |           ~~~~^
p109.cpp:90:6: error: 'i' is not captured
   90 | x += i; // error: i is odr-used but not odr-usable
      |      ^
p109.cpp:86:18: note: the lambda has no capture-default
   86 | auto m3 = [this,m] {
      |                  ^
p109.cpp:72:13: note: 'int i' declared here
   72 | void f1(int i) {
      |         ~~~~^
p109.cpp: In lambda function:
p109.cpp:109:10: error: 'this' was not captured for this lambda function
  109 | return [*this] { }; // error: *this not captured by outer lambda-expression
      |          ^~~~
p109.cpp: In function 'void f2()':
p109.cpp:116:35: error: default argument '<lambda closure object>f2()::<lambda()>{i}.f2()::<lambda()>()' uses local variable 'i'
  116 | void g1(int = ([i]{ return i; })()); // error
      |                                   ^
p109.cpp:117:35: error: default argument '<lambda closure object>f2()::<lambda()>{i}.f2()::<lambda()>()' uses local variable 'i'
  117 | void g2(int = ([i]{ return 0; })()); // error
      |                                   ^
p109.cpp:118:35: error: default argument '<lambda closure object>f2()::<lambda()>{i}.f2()::<lambda()>()' uses local variable 'i'
  118 | void g3(int = ([=]{ return i; })()); // error
      |                                   ^
p109.cpp:122:19: error: local variable 'i' may not appear in this context
  122 | void g7(int = ([x=i]{ return x; })()); // error
      |                   ^
p109.cpp: In lambda function:
p109.cpp:129:5: warning: unused variable 'arr' [-Wunused-variable]
  129 | int arr[N]; // OK, not an odr-use, refers to automatic variable
      |     ^~~

検討事項(agenda)

コンパイルエラーの理由を解説する。

<|--コンパイルエラーを取るか、コンパイルエラーの理由を解説する。-->

参考資料(reference)

typedef は C++11 ではオワコン

C99からC++14を駆け抜けるC++講座

自己参照(self reference)

C++ Error Message Collection(1)does not name a type, 11 articles

dockerにclang

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

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

Compare the contents of C++N4910:2022, C++N4741:2018 and C++N4606:2015

C++ sample list

clang++, g++コンパイルエラー方針の違いの例

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.01 初稿  20220622

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0