Другое

g++ против gcc: какой компилятор выбрать для разработки на C++?

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

В чем разница между компиляторами g++ и gcc, и какой из них следует использовать для общей разработки на C++?

Основное различие между компиляторами g++ и gcc заключается в их стандартной обработке языков и связывании стандартных библиотек: g++ специально разработан для C++ и автоматически связывается со стандартной библиотекой C++, в то время как gcc является компилятором общего назначения, который требует явного указания для кода на C++ и не автоматически включает стандартные библиотеки C++. Для общего разработки на C++ предпочтительным выбором является g++, так как по умолчанию он обрабатывает возможности C++, шаблоны, исключения и стандартную библиотеку, в то время как gcc потребовал бы дополнительных флагов и ручной конфигурации для правильной компиляции кода на C++.

Содержание


Основные различия между gcc и g++

gcc (GNU Compiler Collection) - это компилятор общего назначения, который может компилировать несколько языков программирования, включая C, C++, Objective-C, Fortran, Ada и другие. Изначально он был разработан как компилятор C, но эволюционировал в многоязычную компиляторную платформу.

g++ - это на самом деле просто название GNU компилятора C++ - по сути, это gcc с другими стандартными настройками и поведением, специально настроенными для компиляции C++. Когда вы вызываете g++, вы обычно вызываете gcc с флагами и конфигурациями, специфичными для C++.

Фундаментальное различие заключается в их стандартном поведении:

  • g++ по умолчанию использует режим компиляции C++
  • gcc по умолчанию использует режим компиляции C

“g++ - это компилятор C++ из GNU Compiler Collection. Когда вы компилируете код на C++ с помощью g++, он автоматически включает стандартную библиотеку C++ и устанавливает соответствующие стандарты языка.” - Документация GNU Compiler


Стандарты языка и расширения

gcc для компиляции C++

При использовании gcc для компиляции кода на C++ требуется явное указание языка:

bash
gcc -x c++ source.cpp -o program

или с использованием флага стандарта C++:

bash
gcc -std=c++17 source.cpp -o program

Стандартное поведение g++

g++ автоматически предполагает компиляцию C++:

bash
g++ source.cpp -o program

Основные различия в поддержке языка:

Возможность gcc (с флагами C++) g++ (по умолчанию)
Поддержка шаблонов Требует явного режима C++ Включена по умолчанию
Обработка исключений Требует флага -fexceptions Включена по умолчанию
Информация о типе времени выполнения Требует флага -frtti Включена по умолчанию
Стандартная библиотека C++ Требуется ручное связывание Автоматически связывается

Как объясняется в GCC Wiki, “g++ разработан как интерфейс для C++ к GCC, обеспечивающий правильные стандартные настройки и автоматическое связывание стандартной библиотеки C++.”


Поведение при связывании библиотек

Это одно из самых критических различий между двумя компиляторами:

Связывание библиотек в gcc

При компиляции C++ с помощью gcc обычно требуется вручную указывать стандартные библиотеки C++:

bash
gcc source.cpp -lstdc++ -lm -o program

Связывание библиотек в g++

g++ автоматически включает необходимые стандартные библиотеки C++:

bash
g++ source.cpp -o program

Автоматическое связывание с g++:

  • libstdc++ (стандартная библиотека C++)
  • libm (математическая библиотека)
  • libgcc (поддержка времени выполнения)

В Руководстве по GNU Compiler Collection указано, что “g++ автоматически связывается со стандартной библиотекой C++, в то время как gcc требует явного указания при компиляции кода на C++.”


Когда использовать каждый компилятор

Используйте g++ для:

  • Разработки на C++: Стандартный выбор для всех проектов на C++
  • Смешанных C/C++ проектов: При работе с кодом на C и C++
  • Кода, интенсивно использующего шаблоны: Кода, который сильно полагается на шаблоны C++
  • Использования стандартной библиотеки: Проектов, использующих контейнеры, алгоритмы и потоки ввода-вывода STL
  • Современных возможностей C++: Возможностей C++11, C++14, C++17 и C++20

Используйте gcc для:

  • Чистых C проектов: При работе исключительно с кодом на C
  • Кросс-компиляции: При целевой ориентации на конкретные платформы, где системы сборки ожидают gcc
  • Встраиваемых систем: Средств с ограниченными ресурсами, где предпочтительно минимальное связывание
  • Наследуемых кодовых баз: Старых проектов, разработанных для компиляции с gcc

“Для новых проектов на C++ рекомендуется начинать с g++, так как он обеспечивает наиболее простой опыт компиляции с правильной поддержкой стандартной библиотеки C++.” - C++ FAQ


Практические примеры и использование

Базовые примеры компиляции

Использование g++ (рекомендуется):

bash
# Простая программа на C++
g++ hello.cpp -o hello

# С оптимизацией
g++ -O2 hello.cpp -o hello

# С символами отладки
g++ -g hello.cpp -o hello

# С конкретным стандартом C++
g++ -std=c++20 hello.cpp -o hello

Использование gcc для C++ (не рекомендуется):

bash
# Базовая компиляция C++ с gcc
gcc -x c++ hello.cpp -o hello

# Со стандартом C++
gcc -std=c++17 -lstdc++ hello.cpp -o hello

# С отладкой и оптимизацией
gcc -g -O2 -x c++ -lstdc++ -lm hello.cpp -o hello

Интеграция с системами сборки

Пример CMake (использование g++):

cmake
cmake_minimum_required(VERSION 3.10)
project(MyC++App)

set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(myapp main.cpp)

Пример Makefile:

makefile
CXX = g++
CXXFLAGS = -std=c++17 -Wall -O2
LDFLAGS = 

all: myapp

myapp: main.o
	$(CXX) $(LDFLAGS) -o $@ $^

main.o: main.cpp
	$(CXX) $(CXXFLAGS) -c -o $@ $@

clean:
	rm -f *.o myapp

Соображения относительно производительности

Производительность компиляции

  • gcc и g++ генерируют идентично оптимизированный код при использовании одинаковых флагов оптимизации
  • Различие в производительности заключается в скорости компиляции, а не в качестве генерируемого кода
  • g++ может иметь немного более длительное время компиляции из-за дополнительной C+±специфической обработки

Качество генерируемого кода

При правильной настройке оба компилятора производят:

  • Идентичный машинный код для одного и того же источника
  • Одинаковые уровни оптимизации при использовании эквивалентных флагов
  • Одинаковую производительность времени выполнения

“Фактическая генерация кода идентична между gcc и g++ при использовании одинаковых флагов оптимизации и стандартов языка. Различие заключается в стандартных настройках и автоматическом поведении связывания.” - Руководство по производительности GCC

Использование памяти

  • g++ обычно использует больше памяти во время компиляции из-за инстанцирования шаблонов C++
  • gcc с флагами C++ может иметь меньшее использование памяти для простых проектов на C++

Источники

  1. GNU Compiler Collection - g++ Front End
  2. GCC Wiki - g++ vs gcc
  3. C++ FAQ - Compiler Recommendations
  4. GCC Manual - Overall Options
  5. GNU Compiler Performance Guide

Заключение

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

  1. g++ специально разработан для C++ и обрабатывает все возможности языка C++ по умолчанию
  2. gcc требует явной конфигурации для компиляции C++ и ручного связывания библиотек
  3. Оба компилятора производят идентичный код при правильной настройке с одинаковыми флагами
  4. Используйте g++ для новых проектов на C++ для избежания распространенных проблем компиляции и связывания
  5. Рассматривайте gcc только для чистой разработки на C или конкретных сценариев кросс-компиляции

При начале нового проекта на C++ просто используйте g++ в качестве вашего компилятора выбора. Он обеспечивает наиболее надежный и простой опыт компиляции с автоматической обработкой стандартных библиотек и возможностей языка C++, которые gcc потребовали бы явной настройки для поддержки.

Авторы
Проверено модерацией
Модерация