The C Language and the GCC Compiler
The C Language: A Short Overview
The C programming language is one of the most popular and widespread languages. It is a compiled general-purpose language with static typing. It was developed in 1969-1973 at Bell Labs by Dennis Ritchie.
C is often called a “middle-level” or even “low-level” programming language. It combines high-level language constructs with assembler-like performance and control. It works close to the hardware, which makes low-level data manipulation possible while still giving you structured program flow.
C was originally created for writing the Unix operating system. Later its main area became systems programming: operating systems, drivers, utilities, antivirus tools, and similar software. A large part of Linux is written in C.
C is a compiled language. A compiler translates source code into an executable file made of machine instructions. Platforms differ, so you cannot simply take a compiled program from one platform and run it on another. At the source-code level, though, C programs are portable. Compilers, libraries, and development tools exist for almost every common platform, which means the same source code can be compiled for many targets.
Main Features of C
- Portability: the same source code can be compiled on almost any platform, assuming a suitable compiler exists.
- High execution speed.
- Compact output binaries.
What GCC Is
GCC (GNU Compiler Collection) is a set of compilers and related tools. It includes frontends for C, C++, Objective-C, Fortran, Ada, Go, and other languages. In practice the gcc command is a driver that controls the build stages.
When you run gcc main.c -o app, the driver launches the preprocessor, compiler, assembler, and linker in sequence. You can control these stages with flags: -E for preprocessing only,-S to stop after assembly output, -c to stop at the object file, and then the final link step produces an executable.
GCC is valued for portability, a mature ecosystem, and very detailed documentation. If you need the exact semantics of any flag, the official manual is the right place to check.
Official GCC Documentation
- General documentation index: GCC online documentation
- How compiler invocation works: Invoking GCC
- Full option list: Option Summary
- Installing and building GCC: Installing GCC
- Ready-made binaries by platform: Installing GCC: Binaries
Installing GCC
macOS
brew update
brew install gcc
gcc --versionIf Homebrew is not installed yet, install it first from the official website: brew.sh.
Linux
sudo apt update
sudo apt install build-essential gcc gdb make
gcc --versionThe build-essential package installs the basic toolchain for building C/C++ on Ubuntu/Debian, including gcc, g++, make, and the libc headers.
Documentation and packages: build-essential in Ubuntu Packages, gcc in Ubuntu Packages.
Windows
On Windows the most practical way to build native C code with GCC is to use MSYS2 together with the MinGW-w64 GCC package.
# Open the "MSYS2 UCRT64" terminal
pacman -Suy
# if the terminal closes after the update, open it again and repeat
pacman -Suy
pacman -S --needed mingw-w64-ucrt-x86_64-gcc
gcc --versionWindows installation references: GCC binaries (official GCC page), MSYS2, Updating MSYS2, MinGW-w64: MSYS2 (GCC), the mingw-w64-ucrt-x86_64-gcc package.
Your First C Program
Create a file named hello.c:
#include <stdio.h>
int main(void) {
printf("Hello, C!\n");
return 0;
}Compile and run it:
gcc hello.c -o hello
./helloThe -o hello flag sets the output filename. Without it, GCC usually producesa.out by default.
Useful GCC Flags
A practical baseline command for a C project looks like this:
gcc main.c -std=c23 -Wall -Wextra -Werror -pedantic -O3 -o appLanguage Standard
-std=c23compiles according to the ISO C23 standard.- Common alternatives are
-std=c99,-std=c11, and-std=c17. - If you need the GNU dialect with extensions, use variants such as
-std=gnu11or-std=gnu17.
Documentation: C Dialect Options.
Warnings
-Wallenables a large set of basic warnings, though not literally every possible one.-Wextraadds extra checks on top of-Wall.-Wpedanticwarns about constructs that go beyond the selected C standard.-Werrorturns warnings into errors, which is useful in CI so technical debt does not accumulate.
Documentation: Warning Options.
Optimization
-O0means no optimizations, which is convenient for debugging.-Ogis a compromise: optimizations that interfere less with debugging.-O2is a practical default for production builds.-O3is more aggressive. Sometimes it is faster, sometimes not. You have to measure.-Osoptimizes for binary size.
Documentation: Optimize Options.
Debugging
-gadds debug information forgdband other debuggers.- A common local-development combination is
-Og -g.
Documentation: Debugging Options.
Build and Link Flags
-ccompiles into an object file without linking.-o filesets the output filename.-Ipathadds a header search path.-Lpathand-lnamecontrol the library search path and the library name during linking.
Documentation: Overall Options, Directory Options, Link Options.
Build Stages
GCC goes through several stages: preprocessing, compilation, assembly, and linking. You can inspect them separately:
gcc -E main.c -o main.i # preprocessor
gcc -S main.i -o main.s # C -> ASM
gcc -c main.s -o main.o # ASM -> object
gcc main.o -o app # linkingSummary
C gives you precise control over a program, and GCC gives you a reliable toolchain for building and debugging it. A good baseline habit is to compile with warnings enabled (-Wall -Wextra -Werror -pedantic) and fix them immediately.