はじめに(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つの情報に基づいています。
cpprefjp - C++日本語リファレンス
コンパイラの実装状況
また
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.
27.3 Parallel algorithms [algorithms.parallel] C++N4910:2022 (657) p1151.cpp
算譜(source code)
// C++N4910 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf
const char * n4910 = "27.3 Parallel algorithms [algorithms.parallel] C++N4910:2022 (657) p1151.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 "N4910.h"
using namespace std;
// 27.3.1 Preamble [algorithms.parallel.defns]
// Subclause 27.3 describes components that C++ programs may use to perform operations on containers and other sequences in parallel.
// A parallel algorithm is a function template listed in this document with a template parameter named ExecutionPolicy.
// Parallel algorithms access objects indirectly accessible via their arguments by invoking the following functions:
// A standard library function is vectorization-unsafe if it is specified to synchronize with another function invocation, or another function invocation is specified to synchronize with it, and if it is not a memory allocation or deallocation function.
// [Note 2: Implementations must ensure that internal synchronization inside standard library functions does not prevent forward progress when those functions are executed by threads of execution with weakly parallel forward progress guarantees.
// [Example 2:
int x = 0;
// — All operations of the categories of the iterators that the algorithm is instantiated with.
// — Operations on those sequence elements that are required by its specification.
// — User-provided function objects to be applied during the execution of the algorithm, if required by the specification.
// — Operations on those function objects required by the specification.
// [Note 1: See 27.2.
// These functions are herein called element access functions.
// [Example 1: The sort function may invoke the following element access functions:
// — Operations of the random-access iterator of the actual template argument (as per 25.3.5.7), as implied by the name of the template parameter RandomAccessIterator.
// — The swap function on the elements of the sequence (as per the preconditions specified in 27.8.2.1).
// — The user-provided Compare function object. —end example]
std::mutex m;
void f() {
int a[] = {1,2};
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
std::lock_guard<mutex> guard(m); // incorrect: lock_guard constructor calls m.lock()
++x;
});
}
// The above program may result in two consecutive calls to m.lock() on the same thread of execution (which may deadlock), because the applications of the function object are not guaranteed to run on different threads of execution.
// 27.3.2 Requirements on user-provided function objects [algorithms.parallel.user]
// Unless otherwise specified, function objects passed into parallel algorithms as objects of type Predicate, BinaryPredicate, Compare, UnaryOperation, BinaryOperation, BinaryOperation1, BinaryOperation2, and the operators used by the analogous overloads to these parallel algorithms that are formed by an invocation with the specified default predicate or operation (where applicable) shall not directly or indirectly modify objects via their arguments, nor shall they rely on the identity of the provided objects.
// 27.3.3 Effect of execution policies on algorithm execution [algorithms.parallel.exec]
// Parallel algorithms have template parameters named ExecutionPolicy (22.12) which describe the manner in which the execution of these algorithms may be parallelized and the manner in which they apply the element access functions.
// If an object is modified by an element access function, the algorithm will perform no other unsynchronized accesses to that object. The modifying element access functions are those which are specified as modifying the object.
// [Note 1: For example, swap, ++, --, @=, and assignments modify the object. For the assignment and @= operators, only the left argument is modified.
// Unless otherwise stated, implementations may make arbitrary copies of elements (with type T) from sequences where is_trivially_copy_constructible_v<T> and is_trivially_destructible_v<T> are true.
// [Note 2: This implies that user-supplied function objects cannot rely on object identity of arguments for such input sequences. If object identity of the arguments to these function objects is important, a wrapping iterator that returns a non-copied implementation object such as reference_wrapper<T> (22.10.6), or some equivalent solution, can be used.
// The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution::sequenced_policy all occur in the calling thread of execution.
// [Note 3: The invocations are not interleaved; see 6.9.1.
// The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution::unsequenced_policy are permitted to execute in an unordered fashion in the calling thread of execution, unsequenced with respect to one another in the calling thread of execution.
// [Note 4: This means that multiple function object invocations can be interleaved on a single thread of execution, which overrides the usual guarantee from 6.9.1 that function executions do not overlap with one another.
// The behavior of a program is undefined if it invokes a vectorization-unsafe standard library function from user code called from a execution::unsequenced_policy algorithm.
// [Note 5: Because execution::unsequenced_policy allows the execution of element access functions to be interleaved on a single thread of execution, blocking synchronization, including the use of mutexes, risks deadlock.
// The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution::parallel_policy are permitted to execute either in the invoking thread of execution or in a thread of execution implicitly created by the library to support parallel algorithm execution. If the threads of execution created by thread (33.4.3) or jthread (33.4.4) provide concurrent forward progress guarantees (6.9.2.3), then a thread of execution implicitly created by the library will provide parallel forward progress guarantees; otherwise, the provided forward progress guarantee is implementation-defined. Any such invocations executing in the same thread of execution are indeterminately sequenced with respect to each other.
// [Note 6: It is the caller’s responsibility to ensure that the invocation does not introduce data races or deadlocks.
// [Example 1:
int a[] = {0,1};
std::vector<int> v;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
v.push_back(i*2+1); // incorrect: data race });
// The program above has a data race because of the unsynchronized access to the container v. —end example] [Example 2:
std::atomic<int> x{0};
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
x.fetch_add(1, std::memory_order::relaxed);
// spin wait for another iteration to change the value of x
while (x.load(std::memory_order::relaxed) == 1) { } // incorrect: assumes execution order
});
// The above example depends on the order of execution of the iterations, and will not terminate if both iterations are executed sequentially on the same thread of execution. —end example]
// [Example 3:
int x = 0;
std::mutex m;
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
std::lock_guard<mutex> guard(m);
++x;
});
// The above example synchronizes access to object x ensuring that it is incremented correctly. —end example]
// The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution::parallel_unsequenced_policy are permitted to execute in an unordered fashion in unspecified threads of execution, and unsequenced with respect to one another within each thread of execution. These threads of execution are either the invoking thread of execution or threads of execution implicitly created by the library; the latter will provide weakly parallel forward progress guarantees.
// [Note 7: This means that multiple function object invocations can be interleaved on a single thread of execution, which overrides the usual guarantee from 6.9.1 that function executions do not overlap with one another.
// The behavior of a program is undefined if it invokes a vectorization-unsafe standard library function from user code called from a execution::parallel_unsequenced_policy algorithm.
// [Note 8: Because execution::parallel_unsequenced_policy allows the execution of element access functions to be interleaved on a single thread of execution, blocking synchronization, including the use of mutexes, risks deadlock.
// [Note 9: The semantics of invocation with execution::unsequenced_policy, execution::parallel_policy, or execution::parallel_unsequenced_policy allow the implementation to fall back to sequential execution if the system cannot parallelize an algorithm invocation, e.g., due to lack of resources. —end note]
// If an invocation of a parallel algorithm uses threads of execution implicitly created by the library, then the invoking thread of execution will either
// — temporarily block with forward progress guarantee delegation (6.9.2.3) on the completion of these library-managed threads of execution, or
// — eventually execute an element access function;
// The semantics of parallel algorithms invoked with an execution policy object of implementation-defined type are implementation-defined. the thread of execution will continue to do so until the algorithm is finished.
// [Note 10: In blocking with forward progress guarantee delegation in this context, a thread of execution created by the library is considered to have finished execution as soon as it has finished the execution of the particular element access function that the invoking thread of execution logically depends on.
// 27.3.4 Parallel algorithm exceptions [algorithms.parallel.exceptions]
// During the execution of a parallel algorithm, if temporary memory resources are required for parallelization and none are available, the algorithm throws a bad_alloc exception.
// During the execution of a parallel algorithm, if the invocation of an element access function exits via an uncaught exception, the behavior is determined by the ExecutionPolicy.
// 27.3.5 ExecutionPolicy algorithm overloads [algorithms.parallel.overloads]
// Parallel algorithms are algorithm overloads. Each parallel algorithm overload has an additional template type parameter named ExecutionPolicy, which is the first template parameter. Additionally, each parallel algorithm overload has an additional function parameter of type ExecutionPolicy&&, which is the first function parameter.
// [Note 1: Not all algorithms have parallel algorithm overloads.
// Unless otherwise specified, the semantics of ExecutionPolicy algorithm overloads are identical to their overloads without.
// Unless otherwise specified, the complexity requirements of ExecutionPolicy algorithm overloads are relaxed from the complexity requirements of the overloads without as follows: when the guarantee says “at most expr” or “exactly expr” and does not specify the number of assignments or swaps, and expr is not already expressed with O() notation, the complexity of the algorithm shall be O(expr).
// Parallel algorithms shall not participate in overload resolution unless is_execution_policy_v<remove_- cvref_t<ExecutionPolicy>> is true.
int main() {
cout << n4910 << endl;
return EXIT_SUCCESS;
}
root@8d37178807ec:/home/n4910# vi p1151.cpp
root@8d37178807ec:/home/n4910# astyle < p1151.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 * n4910 = "27.3 Parallel algorithms [algorithms.parallel] C++N4910:2022 (657) p1151.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 "N4910.h"
using namespace std;
// 27.3.1 Preamble [algorithms.parallel.defns]
// Subclause 27.3 describes components that C++ programs may use to perform operations on containers and other sequences in parallel.
// A parallel algorithm is a function template listed in this document with a template parameter named ExecutionPolicy.
// Parallel algorithms access objects indirectly accessible via their arguments by invoking the following functions:
// A standard library function is vectorization-unsafe if it is specified to synchronize with another function invocation, or another function invocation is specified to synchronize with it, and if it is not a memory allocation or deallocation function.
// [Note 2: Implementations must ensure that internal synchronization inside standard library functions does not prevent forward progress when those functions are executed by threads of execution with weakly parallel forward progress guarantees.
// [Example 2:
int x = 0;
// — All operations of the categories of the iterators that the algorithm is instantiated with.
// — Operations on those sequence elements that are required by its specification.
// — User-provided function objects to be applied during the execution of the algorithm, if required by the specification.
// — Operations on those function objects required by the specification.
// [Note 1: See 27.2.
// These functions are herein called element access functions.
// [Example 1: The sort function may invoke the following element access functions:
// — Operations of the random-access iterator of the actual template argument (as per 25.3.5.7), as implied by the name of the template parameter RandomAccessIterator.
// — The swap function on the elements of the sequence (as per the preconditions specified in 27.8.2.1).
// — The user-provided Compare function object. —end example]
std::mutex m;
void f() {
int a[] = {1,2};
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
std::lock_guard<mutex> guard(m); // incorrect: lock_guard constructor calls m.lock()
++x;
});
}
// The above program may result in two consecutive calls to m.lock() on the same thread of execution (which may deadlock), because the applications of the function object are not guaranteed to run on different threads of execution.
// 27.3.2 Requirements on user-provided function objects [algorithms.parallel.user]
// Unless otherwise specified, function objects passed into parallel algorithms as objects of type Predicate, BinaryPredicate, Compare, UnaryOperation, BinaryOperation, BinaryOperation1, BinaryOperation2, and the operators used by the analogous overloads to these parallel algorithms that are formed by an invocation with the specified default predicate or operation (where applicable) shall not directly or indirectly modify objects via their arguments, nor shall they rely on the identity of the provided objects.
// 27.3.3 Effect of execution policies on algorithm execution [algorithms.parallel.exec]
// Parallel algorithms have template parameters named ExecutionPolicy (22.12) which describe the manner in which the execution of these algorithms may be parallelized and the manner in which they apply the element access functions.
// If an object is modified by an element access function, the algorithm will perform no other unsynchronized accesses to that object. The modifying element access functions are those which are specified as modifying the object.
// [Note 1: For example, swap, ++, --, @=, and assignments modify the object. For the assignment and @= operators, only the left argument is modified.
// Unless otherwise stated, implementations may make arbitrary copies of elements (with type T) from sequences where is_trivially_copy_constructible_v<T> and is_trivially_destructible_v<T> are true.
// [Note 2: This implies that user-supplied function objects cannot rely on object identity of arguments for such input sequences. If object identity of the arguments to these function objects is important, a wrapping iterator that returns a non-copied implementation object such as reference_wrapper<T> (22.10.6), or some equivalent solution, can be used.
// The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution::sequenced_policy all occur in the calling thread of execution.
// [Note 3: The invocations are not interleaved; see 6.9.1.
// The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution::unsequenced_policy are permitted to execute in an unordered fashion in the calling thread of execution, unsequenced with respect to one another in the calling thread of execution.
// [Note 4: This means that multiple function object invocations can be interleaved on a single thread of execution, which overrides the usual guarantee from 6.9.1 that function executions do not overlap with one another.
// The behavior of a program is undefined if it invokes a vectorization-unsafe standard library function from user code called from a execution::unsequenced_policy algorithm.
// [Note 5: Because execution::unsequenced_policy allows the execution of element access functions to be interleaved on a single thread of execution, blocking synchronization, including the use of mutexes, risks deadlock.
// The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution::parallel_policy are permitted to execute either in the invoking thread of execution or in a thread of execution implicitly created by the library to support parallel algorithm execution. If the threads of execution created by thread (33.4.3) or jthread (33.4.4) provide concurrent forward progress guarantees (6.9.2.3), then a thread of execution implicitly created by the library will provide parallel forward progress guarantees; otherwise, the provided forward progress guarantee is implementation-defined. Any such invocations executing in the same thread of execution are indeterminately sequenced with respect to each other.
// [Note 6: It is the caller’s responsibility to ensure that the invocation does not introduce data races or deadlocks.
// [Example 1:
int a[] = {0,1};
std::vector<int> v;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
v.push_back(i*2+1); // incorrect: data racea
});
// The program above has a data race because of the unsynchronized access to the container v. —end example] [Example 2:
std::atomic<int> x{0};
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
x.fetch_add(1, std::memory_order::relaxed);
// spin wait for another iteration to change the value of x
while (x.load(std::memory_order::relaxed) == 1) { } // incorrect: assumes execution order
});
// The above example depends on the order of execution of the iterations, and will not terminate if both iterations are executed sequentially on the same thread of execution.]
// [Example 3:
int x = 0;
std::mutex m;
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
std::lock_guard<mutex> guard(m);
++x;
});
// The above example synchronizes access to object x ensuring that it is incremented correctly. —end example]
// The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution::parallel_unsequenced_policy are permitted to execute in an unordered fashion in unspecified threads of execution, and unsequenced with respect to one another within each thread of execution. These threads of execution are either the invoking thread of execution or threads of execution implicitly created by the library; the latter will provide weakly parallel forward progress guarantees.
// [Note 7: This means that multiple function object invocations can be interleaved on a single thread of execution, which overrides the usual guarantee from 6.9.1 that function executions do not overlap with one another.
// The behavior of a program is undefined if it invokes a vectorization-unsafe standard library function from user code called from a execution::parallel_unsequenced_policy algorithm.
// [Note 8: Because execution::parallel_unsequenced_policy allows the execution of element access functions to be interleaved on a single thread of execution, blocking synchronization, including the use of mutexes, risks deadlock.
// [Note 9: The semantics of invocation with execution::unsequenced_policy, execution::parallel_policy, or execution::parallel_unsequenced_policy allow the implementation to fall back to sequential execution if the system cannot parallelize an algorithm invocation, e.g., due to lack of resources. —end note]
// If an invocation of a parallel algorithm uses threads of execution implicitly created by the library, then the invoking thread of execution will either
// — temporarily block with forward progress guarantee delegation (6.9.2.3) on the completion of these library-managed threads of execution, or
// — eventually execute an element access function;
// The semantics of parallel algorithms invoked with an execution policy object of implementation-defined type are implementation-defined. the thread of execution will continue to do so until the algorithm is finished.
// [Note 10: In blocking with forward progress guarantee delegation in this context, a thread of execution created by the library is considered to have finished execution as soon as it has finished the execution of the particular element access function that the invoking thread of execution logically depends on.
// 27.3.4 Parallel algorithm exceptions [algorithms.parallel.exceptions]
// During the execution of a parallel algorithm, if temporary memory resources are required for parallelization and none are available, the algorithm throws a bad_alloc exception.
// During the execution of a parallel algorithm, if the invocation of an element access function exits via an uncaught exception, the behavior is determined by the ExecutionPolicy.
// 27.3.5 ExecutionPolicy algorithm overloads [algorithms.parallel.overloads]
// Parallel algorithms are algorithm overloads. Each parallel algorithm overload has an additional template type parameter named ExecutionPolicy, which is the first template parameter. Additionally, each parallel algorithm overload has an additional function parameter of type ExecutionPolicy&&, which is the first function parameter.
// [Note 1: Not all algorithms have parallel algorithm overloads.
// Unless otherwise specified, the semantics of ExecutionPolicy algorithm overloads are identical to their overloads without.
// Unless otherwise specified, the complexity requirements of ExecutionPolicy algorithm overloads are relaxed from the complexity requirements of the overloads without as follows: when the guarantee says “at most expr” or “exactly expr” and does not specify the number of assignments or swaps, and expr is not already expressed with O() notation, the complexity of the algorithm shall be O(expr).
// Parallel algorithms shall not participate in overload resolution unless is_execution_policy_v<remove_- cvref_t<ExecutionPolicy>> is true.
int main() {
cout << n4910 << endl;
return EXIT_SUCCESS;
}
編纂・実行結果(compile and go)
$ clang++ p1151.cpp -std=03 -o p1151l -I. -Wall
In file included from p1151.cpp:10:
In file included from ./N4910.h:11:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/atomic:38:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/c++0x_warning.h:32:2: error: This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
^
p1151.cpp:32:11: error: no type named 'mutex' in namespace 'std'
std::mutex m;
~~~~~^
p1151.cpp:35:27: error: no member named 'execution' in namespace 'std'; did you mean 'exception'?
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
~~~~~^~~~~~~~~
exception
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/exception.h:60:9: note: 'exception' declared here
class exception
^
p1151.cpp:35:77: error: expected expression
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
^
p1151.cpp:35:38: error: no member named 'par_unseq' in 'std::exception'
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
~~~~~~~~~~~~~~~~^
p1151.cpp:35:54: error: no member named 'begin' in namespace 'std'
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
~~~~~^
p1151.cpp:35:69: error: no member named 'end' in namespace 'std'
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
~~~~~^
p1151.cpp:35:13: error: no member named 'for_each' in namespace 'std'
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
~~~~~^
p1151.cpp:59:25: error: no member named 'execution' in namespace 'std'; did you mean 'exception'?
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
~~~~~^~~~~~~~~
exception
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/exception.h:60:9: note: 'exception' declared here
class exception
^
p1151.cpp:59:11: error: C++ requires a type specifier for all declarations
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
^
p1151.cpp:59:11: error: no member named 'for_each' in namespace 'std'
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
~~~~~^
p1151.cpp:59:69: error: expected expression
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
^
p1151.cpp:59:36: error: no member named 'par' in 'std::exception'
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
~~~~~~~~~~~~~~~~^
p1151.cpp:59:46: error: no member named 'begin' in namespace 'std'
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
~~~~~^
p1151.cpp:59:61: error: no member named 'end' in namespace 'std'
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
~~~~~^
p1151.cpp:63:11: error: no template named 'atomic' in namespace 'std'
std::atomic<int> x{0};
~~~~~^
p1151.cpp:63:24: error: expected ';' after top level declarator
std::atomic<int> x{0};
^
;
p1151.cpp:64:10: error: redefinition of 'a'
int a[] = {1,2};
^
p1151.cpp:57:10: note: previous definition is here
int a[] = {0,1};
^
p1151.cpp:65:25: error: no member named 'execution' in namespace 'std'; did you mean 'exception'?
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
~~~~~^~~~~~~~~
exception
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/exception.h:60:9: note: 'exception' declared here
class exception
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
$ clang++ p1151.cpp -std=2b -o p1151l -I. -Wall
p1151.cpp:32:11: error: no type named 'mutex' in namespace 'std'
std::mutex m;
~~~~~^
p1151.cpp:35:22: error: no member named 'execution' in namespace 'std'; did you mean '__pstl::execution'?
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
^~~~~~~~~~~~~~
__pstl::execution
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/pstl/execution_defs.h:17:11: note: '__pstl::execution' declared here
namespace execution
^
p1151.cpp:36:6: error: no member named 'lock_guard' in namespace 'std'
std::lock_guard<mutex> guard(m); // incorrect: lock_guard constructor calls m.lock()
~~~~~^
p1151.cpp:36:17: error: use of undeclared identifier 'mutex'
std::lock_guard<mutex> guard(m); // incorrect: lock_guard constructor calls m.lock()
^
p1151.cpp:35:8: error: no matching function for call to 'for_each'
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
^~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_algo.h:3833:5: note: candidate function template not viable: requires 3 arguments, but 4 were provided
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
^
p1151.cpp:59:20: error: no member named 'execution' in namespace 'std'; did you mean '__pstl::execution'?
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
^~~~~~~~~~~~~~
__pstl::execution
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/pstl/execution_defs.h:17:11: note: '__pstl::execution' declared here
namespace execution
^
p1151.cpp:59:11: error: C++ requires a type specifier for all declarations
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
^
p1151.cpp:59:25: error: expected unqualified-id
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
^
p1151.cpp:59:70: error: non-local lambda expression cannot have a capture-default
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
^
p1151.cpp:63:23: error: redefinition of 'x' with a different type: 'std::atomic<int>' vs 'int'
std::atomic<int> x{0};
^
p1151.cpp:21:5: note: previous definition is here
int x = 0;
^
p1151.cpp:64:10: error: redefinition of 'a'
int a[] = {1,2};
^
p1151.cpp:57:10: note: previous definition is here
int a[] = {0,1};
^
p1151.cpp:65:20: error: no member named 'execution' in namespace 'std'; did you mean '__pstl::execution'?
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
^~~~~~~~~~~~~~
__pstl::execution
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/pstl/execution_defs.h:17:11: note: '__pstl::execution' declared here
namespace execution
^
p1151.cpp:65:11: error: C++ requires a type specifier for all declarations
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
^
p1151.cpp:65:25: error: expected unqualified-id
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
^
p1151.cpp:65:70: error: non-local lambda expression cannot have a capture-default
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
^
p1151.cpp:66:2: error: member reference base type 'int' is not a structure or union
x.fetch_add(1, std::memory_order::relaxed);
~^~~~~~~~~~
p1151.cpp:68:9: error: member reference base type 'int' is not a structure or union
while (x.load(std::memory_order::relaxed) == 1) { } // incorrect: assumes execution order
~^~~~~
p1151.cpp:72:10: error: redefinition of 'x'
int x = 0;
^
p1151.cpp:21:5: note: previous definition is here
int x = 0;
^
p1151.cpp:73:11: error: no type named 'mutex' in namespace 'std'
std::mutex m;
~~~~~^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
$ g++ p1151.cpp -std=03 -o p1151g -I. -Wall
In file included from /usr/local/include/c++/12.1.0/atomic:38,
from N4910.h:11,
from p1151.cpp:10:
/usr/local/include/c++/12.1.0/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
32 | #error This file requires compiler and library support \
| ^~~~~
p1151.cpp:32:11: error: 'mutex' in namespace 'std' does not name a type
32 | std::mutex m;
| ^~~~~
p1151.cpp:32:6: note: 'std::mutex' is only available from C++11 onwards
32 | std::mutex m;
| ^~~
p1151.cpp: In function 'void f()':
p1151.cpp:35:13: error: 'for_each' is not a member of 'std'
35 | std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
| ^~~~~~~~
p1151.cpp:35:27: error: 'std::execution' has not been declared
35 | std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
| ^~~~~~~~~
p1151.cpp:35:54: error: 'begin' is not a member of 'std'
35 | std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
| ^~~~~
p1151.cpp:35:54: note: 'std::begin' is only available from C++11 onwards
p1151.cpp:35:69: error: 'end' is not a member of 'std'
35 | std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
| ^~~
p1151.cpp:35:69: note: 'std::end' is only available from C++11 onwards
p1151.cpp: In lambda function:
p1151.cpp:36:6: error: 'lock_guard' is not a member of 'std'
36 | std::lock_guard<mutex> guard(m); // incorrect: lock_guard constructor calls m.lock()
| ^~~~~~~~~~
p1151.cpp:36:6: note: 'std::lock_guard' is only available from C++11 onwards
p1151.cpp:36:17: error: 'mutex' was not declared in this scope
36 | std::lock_guard<mutex> guard(m); // incorrect: lock_guard constructor calls m.lock()
| ^~~~~
p1151.cpp:36:17: note: 'std::mutex' is only available from C++11 onwards
p1151.cpp:36:30: error: 'm' was not declared in this scope
36 | std::lock_guard<mutex> guard(m); // incorrect: lock_guard constructor calls m.lock()
| ^
p1151.cpp:36:24: error: 'guard' was not declared in this scope
36 | std::lock_guard<mutex> guard(m); // incorrect: lock_guard constructor calls m.lock()
| ^~~~~
p1151.cpp: In function 'void f()':
p1151.cpp:38:1: warning: lambda expressions only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
38 | }); }
| ^
p1151.cpp: At global scope:
p1151.cpp:59:19: error: expected constructor, destructor, or type conversion before '(' token
59 | std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
| ^
p1151.cpp:61:2: error: expected unqualified-id before ')' token
61 | });
| ^
p1151.cpp:63:11: error: 'atomic' in namespace 'std' does not name a template type
63 | std::atomic<int> x{0};
| ^~~~~~
p1151.cpp:63:6: note: 'std::atomic' is only available from C++11 onwards
63 | std::atomic<int> x{0};
| ^~~
p1151.cpp:64:10: error: redefinition of 'int a []'
64 | int a[] = {1,2};
| ^
p1151.cpp:57:10: note: 'int a [2]' previously defined here
57 | int a[] = {0,1};
| ^
p1151.cpp:65:19: error: expected constructor, destructor, or type conversion before '(' token
65 | std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
| ^
p1151.cpp:69:2: error: expected unqualified-id before ')' token
69 | });
| ^
p1151.cpp:72:10: error: redefinition of 'int x'
72 | int x = 0;
| ^
p1151.cpp:21:5: note: 'int x' previously defined here
21 | int x = 0;
| ^
p1151.cpp:73:11: error: 'mutex' in namespace 'std' does not name a type
73 | std::mutex m;
| ^~~~~
p1151.cpp:73:6: note: 'std::mutex' is only available from C++11 onwards
73 | std::mutex m;
| ^~~
p1151.cpp:74:10: error: redefinition of 'int a []'
74 | int a[] = {1,2};
| ^
p1151.cpp:57:10: note: 'int a [2]' previously defined here
57 | int a[] = {0,1};
| ^
p1151.cpp:75:19: error: expected constructor, destructor, or type conversion before '(' token
75 | std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
| ^
p1151.cpp:77:7: error: expected unqualified-id before ')' token
77 | ++x; });
| ^
$ g++ p1151.cpp -std=2b -o p1151g -I. -Wall
p1151.cpp: In function 'void f()':
p1151.cpp:35:13: error: 'for_each' is not a member of 'std'
35 | std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
| ^~~~~~~~
p1151.cpp:35:27: error: 'std::execution' has not been declared
35 | std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
| ^~~~~~~~~
p1151.cpp: At global scope:
p1151.cpp:59:19: error: expected constructor, destructor, or type conversion before '(' token
59 | std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
| ^
p1151.cpp:61:2: error: expected unqualified-id before ')' token
61 | });
| ^
p1151.cpp:63:23: error: conflicting declaration 'std::atomic<int> x'
63 | std::atomic<int> x{0};
| ^
p1151.cpp:21:5: note: previous declaration as 'int x'
21 | int x = 0;
| ^
p1151.cpp:64:10: error: redefinition of 'int a []'
64 | int a[] = {1,2};
| ^
p1151.cpp:57:10: note: 'int a [2]' previously defined here
57 | int a[] = {0,1};
| ^
p1151.cpp:65:19: error: expected constructor, destructor, or type conversion before '(' token
65 | std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
| ^
p1151.cpp:69:2: error: expected unqualified-id before ')' token
69 | });
| ^
p1151.cpp:72:10: error: redefinition of 'int x'
72 | int x = 0;
| ^
p1151.cpp:21:5: note: 'int x' previously defined here
21 | int x = 0;
| ^
p1151.cpp:73:17: error: redefinition of 'std::mutex m'
73 | std::mutex m;
| ^
p1151.cpp:32:17: note: 'std::mutex m' previously defined here
32 | std::mutex m;
| ^
p1151.cpp:74:10: error: redefinition of 'int a []'
74 | int a[] = {1,2};
| ^
p1151.cpp:57:10: note: 'int a [2]' previously defined here
57 | int a[] = {0,1};
| ^
p1151.cpp:75:19: error: expected constructor, destructor, or type conversion before '(' token
75 | std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
| ^
p1151.cpp:77:7: error: expected unqualified-id before ')' token
77 | ++x; });
| ^
検討事項(agenda)
コンパイルエラーを取るか、コンパイルエラーの理由を解説する。
参考資料(reference)
関連する自己参照以外は、こちらの先頭に移転。
C言語(C++)に対する誤解、曲解、無理解、爽快。
#include "N4910.h"
C++N4910資料の改善点
dockerにclang
docker gnu(gcc/g++) and llvm(clang/clang++)
コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)
C++N4910:2022 tag follower 300人超えました。ありがとうございます。
astyle 使ってみた
DoCAP(ドゥーキャップ)って何ですか?
小川メソッド 覚え(書きかけ)
<この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。>
文書履歴(document history)
ver. 0.01 初稿 20220814