web-dev-qa-db-ja.com

g ++でコンパイルする場合、どのC ++標準がデフォルトですか?

次のようなコードがあります。 example.cppという名前のファイルにあるとします

#include <fstream>
#include <string> // line added after edit for clarity

int main() {
    std::string filename = "input.txt";
    std::ifstream in(filename);

    return 0;
}

Windowsでは、cmdコマンドg++ example.cppを入力すると失敗します。これは、リンカがstringからconst char*に変換できないと文句を言っていることが主な原因だと思うエラーの長いリストです。

しかし、g++ -std=c++17 example.cppのような追加の引数を使用してコンパイラーを実行すると、問題なくコンパイルおよび正常に動作します。

前のコマンドを実行するとどうなりますか?デフォルトを推測しています  C++コンパイラの標準が呼び出されますが、どれがわかりませんか?プログラマー/開発者として、私は常に後者のコマンドを追加の引数とともに使用する必要がありますか?

30
Manuel

g++のバージョンが4.7以降の場合、次のようにサポートされているC++標準のデフォルトバージョンを見つけることができると思います。

g++ -dM -E -x c++  /dev/null | grep -F __cplusplus

私のマシンの例:

mburr@mint17 ~ $ g++ --version | head -1
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
mburr@mint17 ~ $ g++ -dM -E -x c++  /dev/null | grep -F __cplusplus
#define __cplusplus 199711L

いくつかの参照:

40
Michael Burr

C++コンパイラのデフォルトバージョンが呼び出されると思いますが、どれがわかりませんか?

これは、特定のコンパイラバージョンのドキュメントを読むことによってのみ推測できます。

recentGCC を使用している場合は、まず実行して、使用しているバージョンを理解することをお勧めします

g++ -v

または

g++ --version

次に、GCCの特定のリリースのバージョンを参照します。たとえば、GCC 7の場合、 GCC 7の変更 などを読み取ります

または、実行

g++ -dumpspecs

そして、いわゆる spec file と呼ばれるデフォルトを解読します。

ところで、コーディングすることで、C++が少なくともC++ 17であることを確認できます(たとえば、いくつかの共通ヘッダーファイルで)。

 #if __cplusplus < 201412L
 #error expecting C++17 standard
 #endif

実際にそのようにすることをお勧めします。

PS。実際には、C++ 98とC++ 17は2つの異なる言語(たとえば、Ocaml4とC++ 11がそうである)であると考えてください。 GCC の特定のバージョンではなく、定義済みの言語標準(C++ 11など)をサポートするコンパイラーをユーザーに要求します。 パッケージマネージャー についてもお読みください。

10

(少なくともg ++の場合)manページを見ればわかると思います:

-stdの説明の下で、manページにはGNU方言を含むすべてのC++標準がリストされています。ある特定の標準では、This is the default for C++ code.(C標準の類似のステートメント:This is the default for C code.)が目立たないように記述されています。

たとえば、g++/gcc version 5.4.0の場合、これはgnu++98/gnu++03の下にリストされますが、g++/gcc version 6.4.0の場合、gnu++14の下にリストされます。

9
AnInquiringMind

コマンドシェルでg++ --versionと入力すると、コンパイラのバージョンが表示され、そこからデフォルトの標準を推測できます。したがって、直接伝えることはできませんが、inferそれをいくらか努力して行うことができます。

コンパイラは想定 to #define__cplusplusであり、コンパイル時に実装することを意図している標準を抽出するために使用できます。しかし、多くの人はまだこれをしていません。

(そして、必要なすべてのC++標準ライブラリヘッダーを含めることを忘れないでください。たとえば、std::stringのヘッダーはどこですか?他のヘッダーを含むC++標準ライブラリの実装に自動的に依存しないでください。移植可能なC++を書いていない。)

5
Bathsheba

Gdbで確認することもできます

  1. $ g++ example.cpp -g -gフラグを使用してプログラムをコンパイルし、デバッグ情報を生成します
  2. $ gdb a.out gdbを使用したプログラムのデバッグ
  3. (gdb) b main mainにブレークポイントを置きます
  4. (gdb) runプログラムの実行(ブレークポイントで一時停止します)
  5. (gdb) info source

次のようなものを出力します。

Current source file is example.cpp
Compilation directory is /home/xxx/cpp
Located in /home/xxx/cpp/example.cpp
Contains 7 lines.
Source language is c++.
Producer is GNU C++14 6.3.0 20170516 -mtune=generic -march=x86-64 -g.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.

コンパイラで使用される標準があります:Producer is GNU C++14

-std=c++11(たとえば)を使用してプログラムを再コンパイルすると、gdbはそれを検出します:Producer is GNU C++11

4
Benitok

g ++のmanページには、C++コードのデフォルトの標準が実際に記載されています。

次のスクリプトを使用して、関連する部分を表示します。

man g++ | col -b | grep -B 1 -e '-std.* default'

たとえば、RHEL 6 g ++(GCC)4.4.7 20120313(Red Hat 4.4.7-23)では、出力は次のようになります。

         gnu++98
           GNU dialect of -std=c++98.  This is the default for C++ code.

また、Fedora 28 g ++(GCC)8.1.1 20180502(Red Hat 8.1.1-1)では、出力:

       gnu++1y
           GNU dialect of -std=c++14.  This is the default for C++ code.  The name gnu++1y is deprecated.
4
Ding-Yi Chen

あなたの質問はgnuコンパイラに固有のものなので、おそらくC++とC++ 11だけでなく、適切にタグ付けする方が良いでしょう。

コードは、C++ 11以降に準拠したコンパイラ(および関連ライブラリ)でコンパイルされます。

その理由は、C++ 11がstd::ifstreamを受け入れるconst std::string &コンストラクターを導入したためです。 C++ 11より前は、std::stringを渡すことができなかったため、コードでfilenameではなくfilename.c_str()を渡す必要があります。

Gnuの情報によると、 https://gcc.gnu.org/projects/cxx-status.html#cxx11 、gcc.4.8.1はC++ 11を完全にサポートする最初のバージョンでした。コマンドラインでg++ -vg++を生成し、バージョン番号を通知します。

ドキュメントを掘り下げると、最初に十分な機能をサポートしているバージョン/サブバージョンを見つけることができるので、コードが(与えられたとおりに)コンパイルされます。ただし、このようなバージョンでは、C++ 11の一部の機能がサポートされ、他の機能はサポートされません。

Windowsはg ++とともに配布されないため、誰か(あなた?)がインストールするように選択したバージョンがあります。 Windowsのバージョンに関連付けられているg ++のデフォルトバージョンはありません。

3
Peter