Какой стандарт С++ является стандартным при компиляции с 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, он будет компилироваться и работать нормально, без проблем.

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

Ответы

Ответ 1

Если ваша версия g++ более поздняя, ​​чем 4.7, я думаю, вы можете найти стандартную версию стандарта С++, поддерживаемую следующим образом:

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

Пример из моей машины:

[email protected] ~ $ g++ --version | head -1
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
[email protected] ~ $ g++ -dM -E -x c++  /dev/null | grep -F __cplusplus
#define __cplusplus 199711L

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

Ответ 2

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

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

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

g++ -v

или

g++ --version

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

Кроме того, запустите

g++ -dumpspecs

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

В описании -std на странице руководства перечислены все стандарты С++, включая диалоги 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.

Ответ 5

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

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

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

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

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

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

Ответ 6

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