01 · Setup & First Program¶
🎥 Video walkthrough¶
Install a C++ compiler¶
C++ source files are compiled directly to native machine code — there's no virtual machine in between. You need a compiler that implements at least C++17. Pick one for your platform:
# macOS -- Xcode command line tools (provides clang++)
xcode-select --install
# Ubuntu/Debian -- GCC
sudo apt install build-essential
# Windows -- either install MSYS2/MinGW-w64 (g++), or Visual Studio
# Community Edition (includes MSVC's cl.exe and a full IDE)
Verify the install:
g++ --version
# g++ (Homebrew GCC ...) 13.x -- or similar
clang++ --version
# Apple clang version 15.x -- macOS default
Either g++ or clang++ works fine for everything in this course; examples
use g++ but the commands are interchangeable.
Compiling and running by hand¶
Create hello.cpp:
// hello.cpp
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
Compile, then run:
g++ -std=c++17 -Wall -o hello hello.cpp
# produces an executable named "hello"
./hello
# Hello, world!
-std=c++17tells the compiler which language standard to target. Always set this explicitly — the default varies by compiler and version.-Wallturns on common warnings. Treat warnings as bugs waiting to happen; get comfortable reading and fixing them from day one.-o hellonames the output binary; without it you'd geta.out.
Anatomy of the program¶
| Piece | Meaning |
|---|---|
#include <iostream> |
Pulls in the standard I/O library so std::cout is available. |
int main() |
The program's entry point — execution always starts here. |
std::cout << ... |
Streams text to standard output. std:: means "from the standard library's namespace." |
std::endl |
Inserts a newline and flushes the output buffer. |
return 0; |
Tells the operating system the program exited successfully (non-zero means an error occurred). |
; |
Every statement ends with a semicolon. |
{ } |
Curly braces delimit blocks — function bodies, loop bodies, class bodies. |
Header files and translation units¶
Every #include textually pastes in the contents of another file before
compilation. <iostream> is a standard library header — angle brackets
< > tell the compiler to look in its standard include paths. Later, when you
write your own headers, you'll use quotes instead: #include "myheader.h".
Each .cpp file the compiler processes on its own is called a translation
unit; multi-file programs are covered starting in
Module 10.
Namespaces and using namespace std;¶
You'll often see using namespace std; at the top of beginner code so you can
write cout instead of std::cout. It saves typing, but it also pulls
everything from std into scope, which can cause silent name clashes in
larger programs. This course spells out std:: explicitly — it's slightly
more typing but it's what production C++ code does, and it makes clear
exactly where every name comes from.
Choosing an editor¶
Any of these work well for this course: VS Code with the "C/C++" and "CMake Tools" extensions (free, lightweight, great for following along), CLion (excellent C++-specific tooling, paid but free for students), or your platform's default (Xcode on macOS, Visual Studio on Windows). VS Code is the most common lightweight choice — pick one and move on, since the editor matters far less than practice.
How It Actually Works¶
When you run g++/clang++ on a .cpp file, four distinct programs run in
sequence, not one:
- Preprocessor — textually expands
#include(literally pastes the header's contents in), macros, and#ifdefblocks. The output is one huge "translation unit" of pure C++ with no directives left. - Compiler proper — parses that translation unit, type-checks it, and
lowers it to assembly for your target CPU (x86-64, ARM64, ...). This is
where
int main()becomes real machine instructions — a prologue that reserves stack space, instructions for each statement, an epilogue that restores the stack and returns. - Assembler — turns the assembly text into an object file (
.o), raw machine code plus a symbol table (a list of names likemainand where they live in the file, so other tools can find them). - Linker — combines your object file(s) with the C++ standard library's
already-compiled object code (
iostream's internals aren't recompiled — they're pre-built), resolves every symbol reference to a final address, and produces one executable.
This is why a syntax error is a compiler error but calling an undefined function is a linker error ("undefined reference") — the compiler is happy to emit a call to a symbol it hasn't seen the body of yet; only the linker notices nothing defines it. It's also why C++ compiles to native code with no runtime interpreter: the executable you get is CPU instructions the OS loads directly, which is why C++ programs start instantly and why a binary built for macOS/ARM64 won't run on Linux/x86 — there's no portable bytecode layer like a JVM or CLR sits underneath.
🔀 See this in another language¶
Exercise¶
Write a program greeter.cpp with a main function that prints a greeting
for three different names, one per line, using std::cout. Compile it with
g++ -std=c++17 -Wall -o greeter greeter.cpp and run the resulting binary
from the command line.