次のようなコードがあります。 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++コンパイラの標準が呼び出されますが、どれがわかりませんか?プログラマー/開発者として、私は常に後者のコマンドを追加の引数とともに使用する必要がありますか?
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
いくつかの参照:
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など)をサポートするコンパイラーをユーザーに要求します。 パッケージマネージャー についてもお読みください。
(少なくとも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
の下にリストされます。
コマンドシェルでg++ --version
と入力すると、コンパイラのバージョンが表示され、そこからデフォルトの標準を推測できます。したがって、直接伝えることはできませんが、inferそれをいくらか努力して行うことができます。
コンパイラは想定 to #define
__cplusplus
であり、コンパイル時に実装することを意図している標準を抽出するために使用できます。しかし、多くの人はまだこれをしていません。
(そして、必要なすべてのC++標準ライブラリヘッダーを含めることを忘れないでください。たとえば、std::string
のヘッダーはどこですか?他のヘッダーを含むC++標準ライブラリの実装に自動的に依存しないでください。移植可能なC++を書いていない。)
Gdbで確認することもできます
$ g++ example.cpp -g
-gフラグを使用してプログラムをコンパイルし、デバッグ情報を生成します$ gdb a.out
gdbを使用したプログラムのデバッグ(gdb) b main
mainにブレークポイントを置きます(gdb) run
プログラムの実行(ブレークポイントで一時停止します)(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
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.
あなたの質問は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++ -v
はg++
を生成し、バージョン番号を通知します。
ドキュメントを掘り下げると、最初に十分な機能をサポートしているバージョン/サブバージョンを見つけることができるので、コードが(与えられたとおりに)コンパイルされます。ただし、このようなバージョンでは、C++ 11の一部の機能がサポートされ、他の機能はサポートされません。
Windowsはg ++とともに配布されないため、誰か(あなた?)がインストールするように選択したバージョンがあります。 Windowsのバージョンに関連付けられているg ++のデフォルトバージョンはありません。