使用g ++编译时,哪个C++标准是默认的?

Man*_*uel 32 c++ mingw g++

我有一段代码如下所示.让我们说它在一个名为的文件中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;
}
Run Code Online (Sandbox Code Playgroud)

在Windows上,如果我输入cmd命令g++ example.cpp,它将失败.这是一个很长的错误列表,我认为主要是由于链接器抱怨无法转换stringconst char*.

但是如果我使用像这样的附加参数运行编译器:g++ -std=c++17 example.cpp它将编译并正常工作而没有任何问题.

当我运行前命令时会发生什么?我猜测C++编译器的默认版本标准被调用,但我不知道哪个?作为程序员/开发人员,我应该总是使用后一个命令和额外的参数吗?

Mic*_*urr 41

如果您的版本g++低于4.7,我认为您可以找到支持的C++标准的默认版本,如下所示:

g++ -dM -E -x c++  /dev/null | grep -F __cplusplus
Run Code Online (Sandbox Code Playgroud)

我的机器的一个例子:

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
Run Code Online (Sandbox Code Playgroud)

一些参考:

  • 嘿迈克尔,你可以向我解释一下`199711L`吗? (3认同)
  • @RishabhAgrahari 对于“__cplusplus”的解释:/sf/ask/773777231/ 可能会有所帮助。 (2认同)

Bas*_*tch 11

我猜测C++编译器的默认版本被调用,但我不知道哪个?

这只能通过阅读特定编译器版本的文档来猜测.

如果使用最近的 GCC,我建议首先通过运行来了解您使用的是哪个版本

g++ -v
Run Code Online (Sandbox Code Playgroud)

要么

g++ --version
Run Code Online (Sandbox Code Playgroud)

然后参考GCC特定版本的版本.例如,对于GCC 7,请阅读GCC 7更改

或者,跑

g++ -dumpspecs
Run Code Online (Sandbox Code Playgroud)

并解密默认的所谓spec文件.

顺便说一下,你可以通过编码确保(例如在你的一些常见头文件中)C++至少是C++ 17

 #if __cplusplus < 201412L
 #error expecting C++17 standard
 #endif
Run Code Online (Sandbox Code Playgroud)

我实际上建议这样做.

PS.实际上,可以认为C++ 98和C++ 17是两种不同的语言(例如Ocaml4和C++ 11).要求您的用户拥有支持某些已定义语言标准的编译器(例如C++ 11),而不是某些特定版本的GCC.另请阅读包管理器.

  • 如果未指定 -std=xxx,您引用的 [GCC 7 更改](https://gcc.gnu.org/gcc-7/changes.html) 的哪一部分提到哪个 -std=xxx 选项是默认选项? (2认同)

AnI*_*ind 9

我相信通过查看手册页(至少对于g ++)可以看出:

在描述中-std,手册页列出了所有C++标准,包括GNU方言.在一个特定的标准下,它是相当不明确的,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.


Bat*_*eba 5

g++ --version在命令 shell 中键入将显示编译器的版本,您可以从中推断出默认标准。所以你不能直接告诉,但你可以通过一些努力来推断它。

编译器应该#define __cplusplus可以使用的,它们声称在编译时执行提取标准; 但很多人还没有这样做。

(并且不要忘记包含您需要的所有 C++ 标准库头文件:std::string例如,在哪里?不要依赖您的 C++ 标准库实现自动包括其他头文件 - 这样做您不是在编写可移植的 C++。 )

  • 错误,因为 `g++ --version` 仅显示 [GCC](http://gcc.gnu.org/) 编译器的版本,而不是默认标准的版本。 (3认同)
  • @Manuel 你不应该依赖它。始终使用标准库中的“#include”。 (2认同)

Ben*_*tok 5

您也可以使用gdb进行检查

  1. $ g++ example.cpp -g 用-g标志编译程序以生成调试信息
  2. $ gdb a.out 用gdb调试程序
  3. (gdb) b 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.
Run Code Online (Sandbox Code Playgroud)

有编译器使用的标准: Producer is GNU C++14

如果使用-std=c++11(例如)重新编译程序,则gdb将检测到它: Producer is GNU C++11


Din*_*hen 5

g ++手册页实际上告诉了C ++代码的默认标准是什么。

使用以下脚本显示相关部分:

man g++ | col -b | grep -B 1 -e '-std.* default'
Run Code Online (Sandbox Code Playgroud)

例如,在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.
Run Code Online (Sandbox Code Playgroud)

在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.
Run Code Online (Sandbox Code Playgroud)

  • 这依赖于 `gcc` 及其文档之间的一致性,这对于 g++ 12.2.1 无效。手册页上说默认是 C++17,但实际是 C++20。 (4认同)

sol*_*r99 5

男人 g++ | grep "这是 C++ 代码的默认值"