Какой стандарт C++ используется по умолчанию при компиляции с 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;
}

На окнах, если я наберу в cmd команда g++ example.cpp, это не удастся. Это длинный список ошибок, я думаю, в основном из-за того, что компоновщик жалуется на невозможность конвертировать из string в const char*,

Но если я запускаю компилятор, используя дополнительный аргумент, например, так: g++ -std=c++17 example.cpp, он будет компилироваться и нормально работать без проблем.

Что происходит, когда я запускаю прежнюю команду? Я предполагаю, что вызывается стандартный стандарт версии компилятора C++, но я не знаю, какой? И как программист / разработчик, я должен всегда использовать последнюю команду с дополнительным аргументом?

10 ответов

Если ваша версия 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

Некоторые ссылки:

Страница man 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.

Вы также можете проверить с помощью 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.

Существует стандарт, используемый компилятором: Producer is GNU C++14

Если вы перекомпилируете свою программу, используя -std=c++11 (например), GDB обнаруживает это: Producer is GNU C++11

Я считаю, что это можно сказать, посмотрев на страницу руководства (по крайней мере, для g++):

Под описанием -stdНа странице man перечислены все стандарты 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,

Я предполагаю, что вызывается версия компилятора C++ по умолчанию, но я не знаю, какая?

Это возможно только при чтении документации вашей конкретной версии компилятора.

Если вы используете последнюю версию GCC, я рекомендую сначала понять, какую версию вы используете, запустив

g++ -v

или же

g++ --version

а затем обратитесь к версии конкретного выпуска GCC. Например, для GCC 7, прочитайте изменения GCC 7 и т. Д.

Или запустить

g++ -dumpspecs

и расшифровать так называемый spec-файл по умолчанию.

Кстати, вы могли бы гарантировать (например, в некоторых из ваших общих заголовочных файлов), что C++ по крайней мере C++17 путем кодирования

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

и я действительно рекомендую делать это таким образом.

PS. На самом деле, представьте, что C++98 и C++17 - это два разных языка (например, такие как Ocaml4 и C++11). Требуйте, чтобы ваш пользователь имел компилятор, поддерживающий некоторый определенный языковой стандарт (например, C++11), а не какую-то конкретную версию GCC. Читайте также о менеджерах пакетов.

Человек g++ | grep "Это значение по умолчанию для кода C++"

Typing g++ --version в вашей командной оболочке будет показана версия компилятора, и из этого вы сможете вывести стандарт по умолчанию. Таким образом, вы не можете сказать прямо, но можете сделать вывод, приложив некоторые усилия.

Компиляторы должны #define__cplusplus который может быть использован для извлечения стандарта, который они предполагают реализовать во время компиляции; но многие еще этого не делают.

(И не забудьте включить все заголовки стандартной библиотеки C++, которые вам нужны: где std::string например? Не полагайтесь на реализацию стандартной библиотеки C++, включая другие заголовки, автоматически - при этом вы не пишете переносимый C++.)

Ваш вопрос относится к компиляторам gnu, поэтому, вероятно, лучше пометить его соответствующим образом, а не просто C++ и C++11.

Ваш код будет компилироваться с любыми компиляторами (и связанными библиотеками), совместимыми с C++11 и более поздними версиями.

Причина в том, что C++11 ввел std::ifstream конструктор, который принимает const std::string &, До C++11 std::string не может быть передано, и это необходимо в вашем коде для передачи filename.c_str() скорее, чем filename,

Согласно информации от gnu, https://gcc.gnu.org/projects/cxx-status.html, gcc.4.8.1 была первой версией, полностью поддерживающей C++11. В командной строке g++ -v будет подталкивать g++ чтобы сообщить вам свой номер версии.

Если вы покопаетесь в документации, вы сможете найти версию / subversion, которая сначала поддерживала достаточно функций, чтобы ваш код - как указано - компилировался. Но такая версия будет поддерживать некоторые функции C++11, а не другие.

Поскольку Windows не распространяется с g ++, у вас будет любая версия, которую кто-то (вы?) Выбрал для установки. Там не будет версии G ++ по умолчанию, связанной с вашей версией Windows.

Стандарты языков по умолчанию для C и C++ указаны в руководствах GCC. Вы можете найти их следующим образом:

Перейдите на https://gcc.gnu.org/onlinedocs/

Выберите ссылку GCC #.## Manual для интересующей вас версии 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.

Что произойдет, когда я запущу прежнюю команду? Я предполагаю, что вызывается стандарт версии компилятора C++ по умолчанию, но я не знаю, какой именно?

Когда ты бежишьбез указания используемого стандарта языка C++ будет использоваться тот, который будет выбран в качестве стандарта по умолчанию, если он не указан.

Стандарт языка C++ по умолчанию, используемый GCC, зависит от используемой вами версии GCC. См. документацию о статусе поддержки языка C++ GCC , которая на момент написания статьи гласит:

Функции C++17 доступны начиная с GCC 5. Этот режим используется по умолчанию в GCC 11; его можно явно выбрать с помощью флага командной строки -std=c++17 или -std=gnu++17, чтобы также включить расширения GNU.

GCC полностью поддерживает стандарт C++ 2014 года. Этот режим используется по умолчанию в GCC 6.1 вплоть до GCC 10 (включительно); его можно явно выбрать с помощью флага командной строки -std=c++14 или -std=gnu++14, чтобы также включить расширения GNU.

GCC полностью поддерживает стандарт C++ 1998 года, измененный техническим исправлением 2003 года и некоторыми более поздними отчетами о дефектах, за исключением функции экспорта, которая позже была удалена из языка. Этот режим используется по умолчанию в версиях GCC до 6.1; его можно явно выбрать с помощью флага командной строки -std=c++98 или -std=gnu++98, чтобы также включить расширения GNU.

Если вас интересует поддержка языка/стандартной библиотеки для других компиляторов, вы можете просмотреть документацию по поддержке Clang C++ или страницу поддержки компилятора cppreference.com .


И как программист/разработчик, должен ли я всегда использовать последнюю команду с дополнительным аргументом?

Я не знаю, стоит ли вам это делать, но очевидно, что вам придется это сделать, если вы хотите/нужно использовать определенный языковой стандарт, если только тот, который вы хотите/нужно использовать, не является стандартом по умолчанию для версии GCC, который вы используете.

Другие вопросы по тегам