Язык C и компилятор GCC
В этом посте рассказываю о языке C, этапах компиляции и полезных флагах GCC
Язык C: коротко о главном
Язык программирования С (си) — один из самых популярных и распространенных языков. Это компилируемый язык общего назначения со статической типизацией. Его разработал в 1969—1973 годах в компании Bell Labs программист Деннис Ритчи (Dennis Ritchie).
С нередко называют языком программирования «среднего уровня» или даже «низкого уровня». Он сочетает элементы языков высокого уровня с функциональностью и производительностью ассемблера. Работает близко к аппаратной части компьютера. Это позволяет манипулировать данными на низком уровне и использовать высокоуровневые конструкции для управления работой программы.
Изначально С предназначался для написания операционной системы Unix. Позже основной сферой применения стало системное программирование: создание операционных систем, драйверов, утилит, антивирусов и др. Linux большей частью написан на Си.
Си — компилируемый язык. Компилятор переводит исходный код в исполняемый файл с набором машинных инструкций. Платформы отличаются, поэтому скомпилированную программу нельзя просто перенести с одной платформы на другую и там запустить. На уровне исходного кода программы на Си переносимы. Компиляторы, библиотеки и инструменты разработки есть почти под все распространенные платформы. Поэтому один и тот же исходный код на Си можно компилировать в приложения под эти платформы.
Основные особенности Си
- Универсальность — один и тот же код можно скомпилировать почти на каждой платформе (при наличии для нее компилятора).
- Высокая скорость исполнения.
- Компактность — небольшой размер выходных скомпилированных файлов.
Что такое GCC
GCC (GNU Compiler Collection) — это набор компиляторов и сопутствующих инструментов. В него входят фронтенды для C, C++, Objective-C, Fortran, Ada, Go и других языков. На практике команда gcc — это драйвер, который управляет этапами сборки.
Когда вы запускаете gcc main.c -o app, драйвер последовательно запускает препроцессор, компилятор, ассемблер и линковщик. Этими этапами можно управлять через флаги: -E (только препроцессор), -S (до ассемблера), -c (до объектного файла), затем линковка в исполняемый файл.
GCC ценят за переносимость, зрелую экосистему и очень подробную документацию. Если нужна точная семантика любого флага, лучше сразу сверяться с официальным manual.
Официальная документация GCC
- Общий индекс документации: GCC online documentation
- Как работает вызов компилятора: Invoking GCC
- Полный список опций: Option Summary
- Установка и сборка GCC: Installing GCC
- Готовые бинарные сборки по платформам: Installing GCC: Binaries
Установка GCC
macOS
brew update
brew install gcc
gcc --versionЕсли Homebrew ещё не установлен, сначала поставьте его с официального сайта: brew.sh.
Linux
sudo apt update
sudo apt install build-essential gcc gdb make
gcc --versionПакет build-essential ставит базовый набор инструментов для сборки C/C++ на Ubuntu/Debian (включая gcc, g++, make и заголовки libc).
Документация и пакеты: build-essential в Ubuntu Packages, gcc в Ubuntu Packages.
Windows
На Windows самый практичный путь для нативной сборки C через GCC — использовать MSYS2 и пакет MinGW-w64 GCC.
# Открой "MSYS2 UCRT64" терминал
pacman -Suy
# если терминал закрылся после обновления — открой снова и повтори
pacman -Suy
pacman -S --needed mingw-w64-ucrt-x86_64-gcc
gcc --versionДокументация по установке на Windows: GCC binaries (официальная страница GCC), MSYS2, Updating MSYS2, MinGW-w64: MSYS2 (GCC), пакет mingw-w64-ucrt-x86_64-gcc.
Первая программа на C
Создадим файл hello.c:
#include <stdio.h>
int main(void) {
printf("Hello, C!\n");
return 0;
}Компиляция и запуск:
gcc hello.c -o hello
./helloФлаг -o hello задаёт имя выходного файла. Без этого флага по умолчанию создаётся файл a.out.
Полезные флаги GCC
Базовая «рабочая» команда для C-проекта:
gcc main.c -std=c23 -Wall -Wextra -Werror -pedantic -O3 -o appСтандарт языка
-std=c23— компилировать по стандарту ISO C23.- Актуальные альтернативы:
-std=c99,-std=c11,-std=c17. - Если нужен GNU-диалект с расширениями, используйте варианты вида
-std=gnu11,-std=gnu17.
Документация: C Dialect Options.
Предупреждения
-Wall— включает большой набор базовых предупреждений, но не «все возможные».-Wextra— добавляет дополнительные проверки к-Wall.-Wpedantic— предупреждает о конструкциях, выходящих за рамки выбранного стандарта C.-Werror— превращает предупреждения в ошибки (полезно в CI, чтобы не копить технический долг).
Документация: Warning Options.
Оптимизация
-O0— без оптимизаций (по умолчанию), удобно для отладки.-Og— компромисс: оптимизации, которые меньше мешают отладке.-O2— практичный стандарт для production-сборки.-O3— более агрессивные оптимизации; иногда быстрее, иногда нет, нужно измерять.-Os— оптимизация под размер бинарника.
Документация: Optimize Options.
Отладка
-gдобавляет отладочную информацию дляgdbи других дебаггеров.- Типичный вариант для локальной разработки:
-Og -g.
Документация: Debugging Options.
Сборка и линковка
-c— компиляция в объектный файл без линковки.-o file— имя выходного файла.-Ipath— путь к заголовочным файлам.-Lpathи-lname— путь поиска и имя библиотеки при линковке.
Документация: Overall Options, Directory Options, Link Options.
Этапы сборки
GCC проходит несколько шагов: препроцессинг, компиляция, ассемблирование и линковка. Их можно посмотреть отдельно:
gcc -E main.c -o main.i # препроцессор
gcc -S main.i -o main.s # C -> ASM
gcc -c main.s -o main.o # ASM -> object
gcc main.o -o app # линковкаИтог
C даёт точный контроль над программой, а GCC предоставляет надёжный инструмент для сборки и отладки. Хорошая базовая привычка: компилировать с предупреждениями (-Wall -Wextra -Werror -pedantic) и исправлять их сразу.