Skip to content
C++

Hello World and the Compilation Model

Every C++ journey begins with the same two-line ritual: writing a program that prints “Hello, World!” and figuring out how to make the computer run it. The program itself is almost trivially short — but the process that turns it from text on your screen into instructions a CPU can execute is worth understanding deeply. That process is called compilation, and it is the foundation everything else in C++ builds on.

What is a program?

A program is a sequence of instructions that tells a computer exactly what to do, one step at a time. Every action your computer takes — drawing a window, sorting a list, sending a network packet — is ultimately the result of some program running. The CPU itself can only execute instructions in machine code: binary numbers that encode operations at the hardware level. Machine code is not readable by humans, and it is different for every CPU architecture (Intel x86, ARM, RISC-V, and so on).

C++ is a high-level programming language. You write instructions using words and symbols that make sense to humans, and a special program called a compilertranslates that text into machine code for your specific CPU. You write source code once; the compiler produces an executable that the hardware can run directly, at full speed — with no interpreter sitting in between at run-time.

C++ was designed by Bjarne Stroustrup in the early 1980s as an extension of the C language. It adds classes, objects, and many other features while keeping C's ability to generate highly efficient code. Today it powers operating systems, game engines, databases, browsers, and real-time systems where performance cannot be compromised.

Your first program

Create a file called hello.cpp (the .cpp extension identifies C++ source files) and type the following exactly:

#include <iostream>
using namespace std;

int main()
{
    cout << "Hello, World!" << endl;
    return 0;
}

Every line of this program is important. Here is what each piece does:

#include <iostream>

Tells the compiler to include the iostream library, which provides the tools for printing text to the screen (std::cout) and reading text from the keyboard (std::cin). Without this line, the compiler would not know what cout is.

using namespace std;

The standard library lives inside a namespace called std. This line tells the compiler you want to use everything in std without having to type std:: in front of every name. You could also write std::cout every time — and in larger programs, making namespaces explicit is considered better practice — but for short examples this keeps the code clean.

int main()

Every C++ program must have exactly one function called main. Execution always starts here. The int in front means the function returns an integer to the operating system when it finishes. The parentheses () are where parameters would go — this program takes none.

cout << "Hello, World!" << endl;

cout (character output) is the standard output stream — it represents the terminal. The << operator sends data into the stream. endl flushes the stream and moves the cursor to the next line. The entire statement ends with a semicolon, as do all C++ statements.

return 0;

Returns the integer 0 to the operating system. By convention, 0 means the program completed successfully. A non-zero value signals an error. Many modern platforms treat a missing return from main as 0, but it is good practice to be explicit.

The curly braces { } delimit the body of the function — the block of statements that run when main is called. Every opening brace must eventually be paired with a closing brace.

The compilation model

Source code is plain text. Your CPU cannot run plain text — it can only execute binary machine instructions. The journey from .cpp file to running program involves two distinct programs: the compiler and the linker.

From source to executable

1. Write

You write hello.cpp — a plain text file containing C++ source code.

hello.cpp
2. Compile

The compiler (g++, clang++, cl.exe) reads your source file, checks it for syntax errors, and translates it into machine code stored in an object file.

hello.cpp → hello.o
3. Link

The linker combines your object file with the compiled standard library code (which contains the real implementation of cout, endl, etc.) to produce a complete standalone executable.

hello.o + libstdc++ → hello
4. Run

The OS loads the executable into memory and the CPU executes its machine instructions directly.

./hello → Hello, World!

In practice, build systems (including the compiler command itself) typically run the compile and link steps back-to-back so you experience them as one action. But they are logically separate: the compiler works on a single source file; the linker assembles multiple object files into one program.

Compiling and running from the command line

The most direct way to compile is with the g++ command (or clang++ on macOS). Open a terminal in the directory containing hello.cpp and run:

# Compile — creates an executable called "hello" (Linux/macOS)
g++ -std=c++17 -Wall -o hello hello.cpp

# Run it
./hello

The flags matter:

-std=c++17Use the C++17 standard. Modern C++ features require specifying a standard; c++17 or c++20 are safe choices for most programs today.
-WallEnable all common warnings. Warnings are not errors, but they almost always point to genuine bugs. Always compile with -Wall.
-o helloName the output executable hello. Without -o, the output is named a.out on Linux/macOS.
hello.cppThe source file to compile.

On Windows with MSVC, the command looks different: cl /std:c++17 /W4 hello.cpp. Most developers on Windows use an IDE like Visual Studio or Visual Studio Code, which invokes the compiler for you through CMake — covered in the next lesson.

Printing special characters — escape sequences

Some characters cannot be typed directly inside a string literal. A double-quote would end the string prematurely; a backslash would be interpreted as the start of an escape sequence. C++ uses a backslash followed by a letter to represent these characters:

cout << "She said \"Hello.\"" << endl;  // prints: She said "Hello."
cout << "C:\\Users\\Alice"  << endl;  // prints: C:\Users\Alice
cout << "Line one\nLine two"  << endl;  // prints on two lines
SequenceMeaning
\nNewline — moves to the start of the next line
\tTab — horizontal tab character
\"Double quote — use inside a string literal
\'Single quote — use inside a character literal
\\Literal backslash

Note that endl and "\n" both produce a newline, but endl also flushes the output buffer, which is slightly slower. For tight loops, prefer "\n".

Compile-time errors vs run-time errors

Mistakes in a program fall into two categories depending on when they are caught. Compile-time errors are caught by the compiler before the program ever runs — typically because of a syntax violation. Run-time errors (also called logic errors) slip past the compiler and only become visible when the program is actually executing, often producing wrong output or a crash.

Compile-time errors — the compiler catches these

// Error: missing semicolon
cout << "Hello, World!" << endl   // ← compiler error here
return 0;

// Error: missing closing brace
int main()
{
    cout << "Hello" << endl;
    // forgot to close with }

// Error: misspelled keyword or name
Int main()      // 'Int' is not a keyword — C++ is case-sensitive
    cout < "Hello";  // wrong operator, should be <<

Run-time / logic errors — the program compiles but misbehaves

// Compiles fine, but the math is wrong:
double area = width + height;   // should be width * height

// Compiles fine, but prints the wrong text:
cout << "Hello, Wrold!" << endl;  // typo in the string

Compile-time errors are the easier category to deal with: the compiler tells you exactly which line is broken. Run-time errors require you to trace the logic yourself (or use a debugger). The goal of good C++ style is to push as many errors as possible into the compile-time category, where the toolchain catches them for you.

Common first mistakes

Omitting the semicolon

Every statement in C++ ends with a semicolon. Forgetting one is the single most common beginner error. The compiler usually reports it on the line after the missing semicolon — that is where it first realizes something is wrong.

Writing Main instead of main

C++ is case-sensitive. The required entry point is main (lowercase). Main, MAIN, and mAIn are different names. The linker will report 'undefined reference to main' if the entry point is missing or misnamed.

Forgetting #include <iostream>

If you omit the include, the compiler does not know what cout is. The error message typically says 'cout was not declared in this scope'.

Using = instead of == in a comparison

In C++, = is assignment and == is comparison. Writing if (x = 5) assigns 5 to x and always evaluates to true. The compiler warning -Wall will catch this.

Key rules to remember

The compiler translates your source code into machine code; the linker assembles it into an executable

Understanding this two-step process explains why some errors say 'syntax error' (compiler) while others say 'undefined reference' (linker).

Every C++ program must have exactly one main function

Execution starts at main. Having two definitions of main, or misspelling it, produces a linker error.

Every statement ends with a semicolon

Missing semicolons are the most common compile-time error. Get in the habit of checking the end of each statement.

C++ is case-sensitive — main ≠ Main ≠ MAIN

Keywords, function names, and variable names must be typed with the exact capitalization used when they were declared.

Always compile with -Wall

Compiler warnings are almost always pointing at real bugs. Enabling all warnings and fixing them before running the program is much faster than debugging at run-time.

Sign in to track progress