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

时间:2017-06-24 08:16:42

标签: c++ g++ mingw

我有一段代码如下所示。假设它位于名为{ "name": "raphaelscheinkoenig/weblib", "description": "WebLib", "license": "MIT", "authors": [ { "name": "Raphael Scheinkoenig", "email": "scheinkoenig.raphael@gmail.com" } ], "minimum-stability": "stable", "require": { "php": ">=7.0.0" }, "autoload": { "psr-4": { "RaphaelScheinkoenig\\WebLib\\": "src/" } } }

的文件中
example.cpp

在Windows上,如果我输入#include <fstream> #include <string> // line added after edit for clarity int main() { std::string filename = "input.txt"; std::ifstream in(filename); return 0; } 命令cmd,它将失败。我认为这是一长串错误,主要是由于链接器抱怨无法从g++ example.cpp转换为string

但是如果我使用像这样的附加参数运行编译器:const char*,它将编译并正常工作而没有任何问题。

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

9 个答案:

答案 0 :(得分:34)

如果您的g++ -dM -E -x c++ /dev/null | grep -F __cplusplus 版本晚于4.7,我认为您可以找到支持的C ++标准的默认版本:

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

我机器上的一个例子:

/* Print out type, permissions, and number of links. */
printf("%10.10s", sperm (statbuf.st_mode));
printf("%4d", statbuf.st_nlink);

一些参考文献:

答案 1 :(得分:9)

  

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

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

如果使用最近 GCC,我建议您首先了解您正在使用的版本

g++ -v

g++ --version

然后参考GCC特定版本的版本。例如,对于GCC 7,请阅读GCC 7 changes

或者,运行

g++ -dumpspecs

并解密默认的spec file

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

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

我实际上建议那样做。

PS。实际上,想想C ++ 98&amp; C ++ 17是两种不同的语言(例如Ocaml4和C ++ 11)。要求您的用户拥有支持某些已定义语言标准的编译器(例如C ++ 11),而不是某些特定版本的GCC。另请阅读package managers

答案 2 :(得分:7)

我相信可以通过查看手册页(至少对于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下。

答案 3 :(得分:5)

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

编译器假设#define __cplusplus,可用于提取他们声称在编译时实现的标准;但是很多人还没有这样做。

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

答案 4 :(得分:4)

您也可以使用gdb检查

  1. $ g++ example.cpp -g使用-g标志编译程序以生成调试信息
  2. $ gdb a.out使用gdb调试程序
  3. (gdb) b main在主
  4. 处设置断点
  5. (gdb) run运行程序(将在断点暂停)
  6. (gdb) info source
  7. 打印出类似的内容:

    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

答案 5 :(得分:4)

g ++手册页实际上告诉了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.

答案 6 :(得分:3)

您的问题特定于gnu编译器,因此最好适当地标记它,而不仅仅是C ++和C ++ 11。

您的代码将使用符合C ++ 11及更高版本的任何编译器(和相关库)进行编译。

原因是C ++ 11引入了一个接受std::ifstream的{​​{1}}构造函数。在C ++ 11之前,无法传递const std::string &,并且您的代码中必须传递std::string而不是filename.c_str()

根据gnu的信息https://gcc.gnu.org/projects/cxx-status.html#cxx11,gcc.4.8.1是第一个完全支持C ++ 11的版本。在命令行filename将促使g++ -v告诉您其版本号。

如果你深入研究文档,你或许可以找到首先支持足够功能的版本/ subversion,这样你的代码就会被编译。但是这样的版本将支持某些C ++ 11功能,而不支持其他功能。

由于windows不是随g ++一起发布的,因此你会选择安装任何版本的人(你?)。没有与您的Windows版本相关联的g ++的默认版本。

答案 7 :(得分:3)

man g ++ | grep“这是C ++代码的默认设置”

答案 8 :(得分:0)

GCC手册中指定了C和C ++的默认语言标准。您可以找到以下内容:

浏览到https://gcc.gnu.org/onlinedocs/

为您感兴趣的GCC版本选择 GCC#。##手册链接。对于GCC 7.5.0:

https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/

点击主题链接 GCC支持的语言标准,然后是主题 C ++语言(或 C语言)。这些主题中的任何一个都会有一个句子,例如:

如果未提供C ++语言方言选项,则默认值为-std = gnu ++ 14。

如果未提供C语言方言选项,则默认值为-std = gnu11。

以上两个示例适用于GCC 7.5.0。