103

I have a piece of code that looks like the following. Let's say it's in a file named 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;
}

On a windows, if I type in the cmd the command g++ example.cpp, it will fail. It's a long list of errors I think mostly due to the linker complaining about not being able to convert from string to const char*.

But if I run the compiler using an additional argument like so: g++ -std=c++17 example.cpp, it will compile and work fine with no problems.

What happens when I run the former command? I'm guessing a default version standard of the C++ compiler gets called, but I don't know which? And as a programmer/developer, should I always use the latter command with the extra argument?

Manuel
  • 2,143
  • 5
  • 20
  • 22
  • 5
    Depends on your gcc version. – πάντα ῥεῖ Jun 24 '17 at 08:18
  • 3
    Ahem @Downvoters; this is not as obvious as you might think, and this question is well-written with a nice (although non-portable) example. – Bathsheba Jun 24 '17 at 08:37
  • 1
    I presume `-std` changes the semantics of the compiler, rather than run an entirely different complier. Are you interested in the complier ("gcc" vs "clang" vs ...) or standard that the compiler attempts to conform to ("C++17" vs "C++11" vs ....)? – gmatht Jun 24 '17 at 08:45
  • @gmatht the latter is definitely what I'm wondering about. I guess I was misunderstanding a command argument like "-std=c++11" as executing a totally separate compiler. – Manuel Jun 24 '17 at 09:38

10 Answers10

115

If your version of g++ is later than 4.7 I think you can find the default version of C++ standard supported like so:

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

An example from my machine:

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

Some references:

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
29

g++ man page actually tells what is the default standard for C++ code.

Use following script to show the relevant part:

man g++ | col -b | grep -B 2 -e '-std=.* This is the default'

For example, in RHEL 6 g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23), the output:

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

And in Fedora 28 g++ (GCC) 8.1.1 20180502 (Red Hat 8.1.1-1), the output:

       gnu++14
       gnu++1y
           GNU dialect of -std=c++14.  This is the default for C++ code.  The name gnu++1y is deprecated.
Ding-Yi Chen
  • 2,830
  • 33
  • 27
  • 3
    This relies on consistency between `gcc` and its documentation, which is not valid for g++ 12.2.1. The manpage says the default is C++17, but the reality is C++20. – zkoza Jan 31 '23 at 16:57
27

You can also check with gdb

  1. $ g++ example.cpp -g Compile program with -g flag to generate debug info
  2. $ gdb a.out Debug program with gdb
  3. (gdb) b main Put a breakpoint at main
  4. (gdb) run Run program (will pause at breakpoint)
  5. (gdb) info source

Prints out something like:

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.

There is the standard used by compiler: Producer is GNU C++14

If you recompile your program using -std=c++11 (for example), gdb detects it: Producer is GNU C++11

Burrito
  • 1,475
  • 19
  • 27
16

I believe that it is possible to tell by looking at the man page (at least for g++):

Under the description of -std, the man page lists all C++ standards, including the GNU dialects. Under one specific standard, it is rather inconspicuously stated, This is the default for C++ code. (there is an analogous statement for C standards: This is the default for C code.).

For instance, for g++/gcc version 5.4.0, this is listed under gnu++98/gnu++03, whereas for g++/gcc version 6.4.0, this is listed under gnu++14.

AnInquiringMind
  • 773
  • 1
  • 7
  • 13
15

I'm guessing a default version of the C++ compiler gets called, but I don't know which?

This is only guessable by reading the documentation of your particular compiler version.

If using a recent GCC, I recommend first to understand what version are you using by running

g++ -v

or

g++ --version

and then refer to the version of the particular release of GCC. For example for GCC 7, read GCC 7 changes etc

Alternatively, run

g++ -dumpspecs

and decipher the default so called spec file.

BTW, you could ensure (e.g. in some of your common header file) that C++ is at least C++17 by coding

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

and I actually recommend doing it that way.

PS. Actually, think of C++98 & C++17 being two different languages (e.g. like Ocaml4 and C++11 are). Require your user to have a compiler supporting some defined language standard (e.g. C++11), not some particular version of GCC. Read also about package managers.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 2
    Which part of your quoted [GCC 7 changes](https://gcc.gnu.org/gcc-7/changes.html) mentions which -std=xxx option is the default if -std=xxx is not specified? – DodgyCodeException Jan 16 '18 at 15:31
  • Each version of the GCC compiler documentation explicitly states the default language standard for both C and C++. No guessing required. See my answer, below. – MikeOnline Sep 30 '20 at 00:49
10

If you are using the GCC compiler, you can find it on the man pages:

man g++ | grep "This is the default for C++ code"

Mehedi H.
  • 137
  • 2
  • 6
6

Typing g++ --version in your command shell will reveal the version of the compiler, and from that you can infer the default standard. So you can't tell directly but you can infer it, with some effort.

Compilers are supposed to #define __cplusplus which can be used to extract the standard that they purport to implement at compile time; but many don't do this yet.

(And don't forget to include all the C++ standard library headers you need: where is the one for std::string for example? Don't rely on your C++ standard library implementation including other headers automatically - in doing that you are not writing portable C++.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
4

Your code will compile with any compilers (and associated libraries) compliant with C++11 and later.

The reason is that C++11 introduced a std::ifstream constructor that accepts a const std::string &. Before C++11, a std::string could not be passed, and it would be necessary in your code to pass filename.c_str() rather than filename.

According to information from gnu, https://gcc.gnu.org/projects/cxx-status.html#cxx11, gcc.4.8.1 was the first version to fully support C++11. At the command line g++ -v will prod g++ to telling you its version number.

If you dig into documentation, you might be able to find the version/subversion that first supported enough features so your code - as given - would compile. But such a version would support some C++11 features and not others.

Since windows isn't distributed with g++, you will have whatever version someone (you?) has chosen to install. There will be no default version of g++ associated with your version of windows.

starball
  • 20,030
  • 7
  • 43
  • 238
Peter
  • 35,646
  • 4
  • 32
  • 74
2

The default language standards for both C and C++ are specified in the GCC Manuals. You can find these as follows:

Browse to https://gcc.gnu.org/onlinedocs/

Select the GCC #.## Manual link for the version of GCC you are interested in, e.g. for GCC 7.5.0:

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

Click the topic link Language Standards Supported by GCC, followed by the topic C++ Language (or C language). Either of these topics will have a sentence such as:

The default, if no C++ language dialect options are given, is -std=gnu++14.

The default, if no C language dialect options are given, is -std=gnu11.

The above two examples are for GCC 7.5.0.

MikeOnline
  • 994
  • 11
  • 18
0

What happens when I run the former command? I'm guessing a default version standard of the C++ compiler gets called, but I don't know which?

When you run g++ without specifying a C++ language standard to use, it will use whichever one was decided to be the default when none is specified.

The default C++ language standard used by GCC depends on the version of GCC you're using. See GCC's C++ language support status documentation, which at the time of this writing states:

C++17 features are available since GCC 5. This mode is the default in GCC 11; it can be explicitly selected with the -std=c++17 command-line flag, or -std=gnu++17 to enable GNU extensions as well.

GCC has full support for the of the 2014 C++ standard. This mode is the default in GCC 6.1 up until GCC 10 (including); it can be explicitly selected with the -std=c++14 command-line flag, or -std=gnu++14 to enable GNU extensions as well.

GCC has full support for the 1998 C++ standard as modified by the 2003 technical corrigendum and some later defect reports, excluding the export feature which was later removed from the language. This mode is the default in GCC versions prior to 6.1; it can be explicitly selected with the -std=c++98 command-line flag, or -std=gnu++98 to enable GNU extensions as well.

If you're interested in language / standard library support for other compilers as well, you can see Clang's C++ support documentation or cppreference.com's compiler support page.


And as a programmer/developer, should I always use the latter command with the extra argument?

I don't know about whether you should, but the obvious is that you'll need to if you want/need to use a specific language standard, unless the one you want/need to use happens to be the default for the version of GCC you're using.

starball
  • 20,030
  • 7
  • 43
  • 238