From source file to running program
Starting out10 min readLesson 1 of 5
1.1 From text to machine code
C is a compiled language. You type C into a file ending in .c, and a set of programs turns that file into instructions the processor can run. The set is called a toolchain.
A build passes through four stages:
- the preprocessor replaces
#includelines with the contents of the named header and expands macros - the compiler checks the C and translates it into assembly for the target processor
- the assembler turns that assembly into an object file
- the linker joins your object files with library code and writes the final program
You normally see one command and one result. The stages show up when something goes wrong. A message about undefined reference comes from the linker. A missing header message comes from the preprocessor.
#include <stdio.h>
int main(void)
{
printf("Hello from a C program.\n");
return 0;
}Output
Hello from a C program.
1.2 Building the file
Save the program as hello.c, open a terminal in that folder, and run one build command.
With GCC:
gcc -std=c17 -Wall -Wextra hello.c -o hello
With Clang:
clang -std=c17 -Wall -Wextra hello.c -o hello
With the Microsoft compiler on Windows:
cl /std:c17 /W4 hello.c
-Wall and -Wextra turn on warnings. -std=c17 asks for the C17 standard. /W4 and /std:c17 are the Microsoft spellings. The compiler writes an executable named hello, or hello.exe on Windows.
Run it with ./hello on Linux or macOS. In Windows PowerShell the command is .\hello.exe. Command Prompt searches the current folder first, so hello works there.
A build that succeeds prints nothing. The compiler speaks only when it has something to report.
#include <stdio.h>
int main(void)
{
puts("puts ends the line for you.");
printf("printf waits for an explicit newline.");
printf("\n");
return 0;
}Output
puts ends the line for you. printf waits for an explicit newline.
1.3 What main does
Every C program that runs on its own needs a function called main. The operating system starts the program by calling it. The signature int main(void) has two parts worth reading:
intis the type of the valuemainhands back to the systemvoidin the parameter list says the function takes no arguments
return 0; reports success. A shell stores the status in $? on Linux and macOS, and in %ERRORLEVEL% in Windows Command Prompt. A nonzero value usually means something failed.
Statements inside the braces run from top to bottom, and each one ends with a semicolon. The braces { and } mark the block that belongs to main.
#include <stdio.h>
int main(void)
{
printf("This program reports a failure status on purpose.\n");
return 2;
}Output
This program reports a failure status on purpose.
1.4 Reading the messages
When a build fails, start with the first message. Later messages often follow from the first one.
hello.c:4:5: error: expected ';' before '}' tokenpoints at line 4, column 5. Go to that line; a missing semicolon is the usual cause.fatal error: stdio.h: No such file or directorymeans the toolchain cannot find a standard header, which points to an installation problem.undefined reference to 'main'comes from the linker: the file compiled, and the program has nomainto start from.
Fix one problem, build again, and read the new output. The error count falls as you repair the early messages.
#include <stdio.h>
int main(void)
{
int limit = 10; /* never used: -Wall reports this */
printf("Warnings do not stop the build.\n");
return 0;
}Output
Warnings do not stop the build.
1.5 Which C standard
The language has been standardised several times. C89, C99, C11, C17, and C23 are the usual names, and each later one changed the language. C17 fixed defects in C11 and added almost nothing that a beginner would notice. C23, published in 2024, adds keywords and syntax that older compilers reject.
The examples in this course use features that compile under C17 and also under C23. When you read code online, the comment at the top often names the standard it needs. If a compiler rejects bool without <stdbool.h>, check the compiler's standard setting before you edit the file.
#include <stdio.h>
int main(void)
{
int answer = 6 * 7;
printf("Six times seven is %d.\n", answer);
return 0;
}Output
Six times seven is 42.
1.6 Practice
- Save the hello program as
hello.cand build it with the command for your compiler. - Run the executable and check the message.
- Delete the semicolon at the end of the
printfline. Build again and read the first message. Put the semicolon back. - Change the text inside
printfand rebuild. Only the printed line should change.
