我有一段代码如下所示。假设它位于名为{
"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 ++编译器的默认版本标准被调用,但我不知道哪个?作为程序员/开发人员,我应该总是使用后一个命令和额外的参数吗?
答案 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检查
$ g++ example.cpp -g
使用-g标志编译程序以生成调试信息$ gdb a.out
使用gdb调试程序(gdb) b 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
答案 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。