C sits underneath a huge amount of software: operating system kernels, embedded firmware, databases, and the runtimes of many other languages. It is a compiled language, so the workflow is always the same: write source files, hand them to a compiler, and run the native executable it produces. This chapter gets a compiler onto your machine, builds a first program, turns on the warnings you want, and looks at what actually happens during a build.
Installing a compiler
There are three mainstream C compilers: GCC, Clang, and Microsoft's MSVC. Standard C code builds with any of them, so pick whichever is easiest to get on your platform.
Confirm the compiler is on your PATH:
gcc --version
clang --version
# MSVC: run inside a "Developer Command Prompt"
cl
MSVC needs a set of environment variables that plain terminals do not have, so use the Developer Command Prompt (or Developer PowerShell) that Visual Studio installs.
Your first program
Save this as hello.c:
#include <stdio.h>
int main(void) {
printf("Hello, C!\n");
return 0;
}
The #include line pulls in the declarations for the standard I/O functions. Every program starts executing in main, and the value it returns becomes the process exit status, where 0 means success.
Build and run it:
# GCC or Clang
gcc -std=c17 -Wall -Wextra -g hello.c -o hello
./hello
echo $? # prints the exit status, 0
# MSVC (Developer Command Prompt)
cl /std:c17 /W4 hello.c
hello.exe
-o hello names the output; without it GCC and Clang write a.out. -std=c17 pins the language standard so you are not relying on whatever default the compiler picked, and -g embeds debug information for tools like GDB or LLDB. Add an optimization level such as -O2 for release builds.
Turn the warnings up
Out of the box, C compilers accept a lot of code that is almost certainly wrong. Enabling warnings costs nothing and catches real bugs, so make it a habit from day one.
-Wall enables a broad set of common-mistake warnings. Despite the name, it is not every warning.-Wextra adds more checks on top, such as unused parameters.-Wpedantic flags compiler extensions that are not part of standard C.-Werror turns warnings into errors, which is handy in CI so warnings never pile up.- On MSVC,
/W4 is the rough equivalent and /WX treats warnings as errors.
This program compiles, but it contains two mistakes:
#include <stdio.h>
int area(int width, int height) {
return width * width; /* height is never used */
}
int main(void) {
printf("%d\n", 3.5); /* passes a double to %d */
return area(2, 3) == 4 ? 0 : 1;
}
With -Wall -Wextra, the compiler reports the format/argument mismatch in printf and the unused height parameter. Without warnings, you would only find out at run time through a nonsensical value.
What a build really does
That single gcc hello.c -o hello command runs four stages in sequence:
- Preprocessing: pastes in
#include files, expands #define macros, and resolves #if conditionals. - Compilation: translates the preprocessed C into assembly. Syntax errors and most warnings come from here.
- Assembly: turns assembly into an object file (
.o, or .obj on Windows) containing machine code. - Linking: combines object files and libraries into an executable. "undefined reference" errors come from this stage.
You can stop after each stage and inspect the output:
gcc -E hello.c -o hello.i # preprocessed source
gcc -S hello.i -o hello.s # assembly
gcc -c hello.s -o hello.o # object file
gcc hello.o -o hello # link
Real projects compile each source file to an object file with -c and link them all at the end. Only files that changed need recompiling, which keeps builds fast. Chapter 4 builds on this with Make and CMake.
Summary
- Install GCC, Clang, or MSVC and verify it with
--version. - Execution starts in
main; returning 0 signals success. - Build with
-std=c17 -Wall -Wextra (or /W4 on MSVC) so the compiler catches mistakes early. - A build is preprocess, compile, assemble, link. Knowing which stage produced an error tells you where to look.
0 Kommentare
Anmelden · Melde dich an, um einen Kommentar zu schreiben.