В чем разница между g++ и gcc при компиляции C++ кода?
Основное различие: gcc vs g++
Вы абсолютно правы: GCC расшифровывается как GNU Compiler Collection, и технически он поддерживает множество языков, включая C, C++, Objective-C, Fortran и другие. Однако в контексте команд gcc и g++ ключевое отличие заключается в том, как они обрабатывают линковку (связывание объектных файлов в исполняемый).
Почему gcc не работает с C++ кодом?
Вот что происходит под капотом:
- gcc по умолчанию настраивается как драйвер для компиляции C-кода. Когда вы передаете ему файл
.cpp, он все равно может распознать синтаксис C++ (если файл имеет соответствующее расширение), но при линковке он не подключает стандартную библиотеку C++ (libstdc++). В результате символы вродеstd::cout,std::endlи другие остаются неразрешенными — отсюда ошибкиundefined reference. - g++ — это тот же GCC, но настроенный как драйвер для C++. Он автоматически добавляет флаги линковки для libstdc++ и других библиотек C++ (например, libsupc++ для обработки исключений). Кроме того, он по умолчанию включает поддержку RTTI (Run-Time Type Information) и исключений.
Как заставить gcc работать с C++?
Если вы по каким-то причинам хотите использовать именно gcc для компиляции C++, вам нужно явно указать флаги линковки:
gcc test.cpp -o test -lstdc++
Флаг -lstdc++ подключает библиотеку libstdc++. Однако это не рекомендуется, потому что gcc не будет автоматически добавлять другие важные флаги (например, -shared-libgcc для динамической линковки с libgcc). Лучше всегда используйте g++ для C++.
Дополнительные отличия
- Расширения файлов:
gccвоспринимает файлы.cкак C, а.cpp,.cc,.cxx— как C++.g++считает все перечисленные расширения C++ (даже.c). - Стандартные библиотеки:
g++автоматически линкует libstdc++ и libm (математическую библиотеку).gccэтого не делает. - Исключения и RTTI:
g++включает поддержку исключений и RTTI по умолчанию.gccможет их отключить, если не указать флаги.
Практический пример
Создадим два файла: main.cpp (C++) и helper.c (C):
// main.cpp
#include <iostream>
extern "C" void hello_from_c(); // объявляем C-функцию
int main() {
std::cout << "Hello from C++!" << std::endl;
hello_from_c();
return 0;
}
// helper.c
#include <stdio.h>
void hello_from_c() {
printf("Hello from C!\n");
}
Компиляция смешанного проекта:
g++ -c main.cpp -o main.o
gcc -c helper.c -o helper.o
g++ main.o helper.o -o program
./program
// Вывод:
// Hello from C++!
// Hello from C!
Обратите внимание: для линковки мы снова используем g++, чтобы подключить libstdc++. Если бы мы попробовали gcc main.o helper.o -o program, получили бы ошибку линковки из-за отсутствия стандартной библиотеки C++.
Резюме
- Всегда используйте
g++для компиляции C++ кода — это правильный и простой путь. gccподходит только для чистого C или для случаев, когда вы явно управляете флагами линковки.- Не пытайтесь "экономить" на командах — различие в одну букву сэкономит вам часы отладки.
Альтернативный взгляд: это историческое наследие
Многие путаются из-за названия. Исторически gcc изначально означал GNU C Compiler (компилятор только для C). Когда проект расширился до поддержки C++, Fortran и других языков, его переименовали в GNU Compiler Collection, но имя команды gcc осталось как синоним компилятора C. А g++ был добавлен как специализированный драйвер для C++.
На самом деле, если посмотреть на исполняемые файлы в папке MinGW, вы увидите, что gcc.exe и g++.exe — это один и тот же бинарник (или очень похожие). Разница только в том, как они обрабатывают аргументы командной строки. Например, в Linux можно проверить:
ls -la /usr/bin/gcc /usr/bin/g++
# Скорее всего, это симлинки на один и тот же файл
Поэтому, если вам нужно скомпилировать одиночный файл на C++, просто используйте g++. Если вы работаете с большим проектом, где есть и C, и C++ код, используйте CMake или Makefile — они автоматически выберут правильный компилятор для каждого файла. Например, в CMake достаточно указать:
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_C_COMPILER gcc)
Это избавит вас от ручной возни с флагами.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги