警告 warning: XX is a C++11 extension [-Wc++11-extensions] の対処【-Wc++1z-extensions】

C++のコンパイラでソースコードのコンパイルを行うと、以下のような警告やエラーが発生する事がある。

// warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto shop = 99;
// warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
struct T { int v = 9; };
// warning: nested namespace definition is a C++1z extension; define each namespace separately [-Wc++1z-extensions]
namespace a::b {}
// error: 'auto' return without trailing return type; deduced return types are a C++14 extension
auto f() {}

C++11やC++14等の最新の規格に対応していない古い処理系でコンパイルを行うと、上記のような警告が発生する原因となる。warning:についてはあくまで警告であるため、コンパイル自体は成功する。これらの警告やエラーを解消するためには、コンパイラフラグ-stdの指定によって最新の規格を用いるようにする必要がある。

// C++11 // [-Wc++11-extensions]
clang++ main.cpp -std=c++11
g++     main.cpp -std=c++0x // 実験版: 古いGCC/GNUコンパイラで利用
// C++14 // "a C++14 extension"
clang++ main.cpp -std=c++14
clang++ main.cpp -std=c++1y // 実験版: 古いコンパイラで利用
// C++17 // [-Wc++1z-extensions], [-Wc++17-extensions]
clang++ main.cpp -std=c++17
clang++ main.cpp -std=c++1z // 実験版: 古いコンパイラで利用

C++11/C++14に対応しているコンパイラを利用しているにもかかわらず、デフォルトの標準規格が一世代前のC++03/C++11になっているような場合もある。その場合はコンパイルオプションとしてそれぞれ-std=c++11/-std=c++14を明示的に指定してコンパイルする必要がある。

[-Wc++11-extensions]警告解消後に同一箇所で新たなエラーが発生する場合は、C++14/C++17の記法が用いられている可能性が疑われるため、-std=c++14/-std=c++17フラグも試してみるとよい。

[-Wc++1z-extensions][-Wc++17-extensions]の警告については、ソースコード内でC++17の記法などが使われているため、それぞれ-std=c++1z-std=c++17を利用して対処する。

なお、c++0xc++1yc++1z等のフラグでは実験的な機能のみが提供されているため、一部利用できない機能もある。

/* clang++ main.cpp -std=c++1z */
// error: unexpected namespace name 'a': expected expression
auto [a, b] = std::make_tuple("a", "b");

この場合、よりバージョンの新しいコンパイラや、C++11/C++14/C++17に完全対応した最新のコンパイラを新しく用意する必要がある。

広告