The four-line C++ “Hello, World!” takes 277 milliseconds to compile on the machine used for this article. The equivalent C program takes 30. Nothing in the four lines explains the difference — the #include does, and that is the first genuinely useful thing a beginner can learn from this program.
Most Hello World tutorials give you a code block and a screenshot. This one gives you the code, the captured output, the exact commands to compile and run it on Windows, Linux and macOS, the C++23 two-line version, and the four compiler errors you are most likely to hit — quoted verbatim from the compiler rather than paraphrased. If you want the C version of the same program, we have a companion walkthrough of the Hello World program in C. Every program on this page was compiled and run for this article on Ubuntu 24.04 with GCC 13.3 and GCC 14.2, using -Wall -Wextra with zero warnings. Every output block and every error message is captured verbatim.
What Is a “Hello, World!” Program in C++?
A “Hello, World!” program is a minimal C++ program that produces a single, recognisable line of output. It includes <iostream>, defines main(), and writes a single line of text to standard output. Its purpose is not to teach printing — it is to prove that your compiler, your linker and your terminal all work together before you write anything that matters.
That last point is why the program has outlived every language it was first written in. It is a build-system test wearing a greeting. When it fails, the failure tells you something specific about your setup, which is why the error section below is the most useful part of this page for most readers. The output machinery it exercises lives in the C++ input/output library.
<iostream> and std::cout, annotated line by line, alongside the two-line C++23 form using <print> and std::println. Both produce identical output; the C++23 version requires GCC 14+, Clang 18+ with libc++, or MSVC 19.37+ and -std=c++23.
The C++ Hello World Program
// hello.cpp - a first C++ program
#include <iostream>
int main() {
std::cout << "Hello, World!\n";
return 0;
}
Output:
Hello, World!
The comment and the explicit return 0; are shown here for clarity — strip them and the program is four lines, which is the form in the diagram above. Four lines of substance, then, and each one is doing a distinct job.
| Line | What it does |
|---|---|
#include <iostream> | Tells the preprocessor to paste in the declarations for the standard input/output streams, including std::cout. |
int main() | The entry point. Execution starts here no matter where in the file the function sits. It returns int — never void. |
std::cout << "Hello, World!\n"; | Sends the text to standard output. << is the stream insertion operator; \n ends the line. |
return 0; | Reports success to the operating system. In main — and only in main — you may omit it — reaching the end of main is defined to return zero. |
Two details are worth pausing on, because almost every older tutorial gets them wrong.
std:: is not noise. cout lives in the std namespace, and writing std::cout says so. Older tutorials open with using namespace std; to avoid typing four characters, then write std::cout anyway in the same program — a contradiction that teaches nothing. In a file this size the directive is harmless; in a real project it makes every name in the standard library a candidate for unqualified lookup, and collisions become a matter of time. Learn the qualified form first and you will never have to unlearn it.
A line of output should end with \n. Drop it and the program still compiles and still “works” — but the shell prompt lands on the same line as your output:
Hello, World!user@host:~$
That is the single most common reason a beginner thinks their first program is broken when it isn’t.
How to Compile and Run It
Save the file as hello.cpp, then use the toolchain for your platform. If you have not installed one yet, our guide to the best C++ compilers covers the trade-offs between GCC, Clang and MSVC.
| Platform | Compile | Run |
|---|---|---|
| Linux (GCC) | g++ -std=c++17 -Wall -Wextra hello.cpp -o hello | ./hello |
| macOS (Clang) | clang++ -std=c++17 -Wall -Wextra hello.cpp -o hello | ./hello |
| Windows (MSVC, Developer Command Prompt) | cl /std:c++17 /EHsc /W4 hello.cpp | hello.exe |
| Windows (MinGW-w64) | g++ -std=c++17 -Wall -Wextra hello.cpp -o hello.exe | hello.exe |
Turn the warnings on from day one. -Wall -Wextra (or /W4 on MSVC) costs nothing on a program this size and will catch real mistakes in the programs you write next week. A beginner who compiles with warnings enabled is already ahead of a large amount of published C++ code.
If you are using an IDE — Visual Studio, CLion, Code::Blocks, VS Code — the build button runs one of these commands for you. It is still worth compiling by hand once, so that the IDE is a convenience rather than a black box.
The C++23 Version: std::println
C++23 added a formatted output library that reduces the whole program to two lines:
// hello23.cpp - the C++23 version
#include <print>
int main() {
std::println("Hello, World!");
}
Output:
Hello, World!
std::println appends the newline for you, which removes the most common beginner mistake by construction. It also checks the format string against its arguments at compile time, so the mismatched-specifier bugs that plague printf become compiler errors rather than garbage output.
The catch is availability. This needs a recent toolchain, and on an older one the failure is immediate and unmistakable — here is GCC 13.3 refusing the same file:
hello23.cpp:2:10: fatal error: print: No such file or directory
2 | #include <print>
| ^~~~~~~
compilation terminated.
| Toolchain | First version with <print> |
|---|---|
| GCC (libstdc++) | 14 |
| Clang (libc++) | 18 (17 partial) |
| MSVC STL | 19.37 — Visual Studio 2022 17.7 |
| Apple Clang | 16.0.0 |
Those figures are from the cppreference C++23 compiler support table, checked this session, for the <print> header (paper P2093R14). Compile with -std=c++23 on GCC and Clang, or /std:c++latest on MSVC. Note that availability is decided by the standard library, not the compiler front end alone: a compiler can accept -std=c++23 and still have no header, which is exactly the GCC 13.3 failure above. Third-party summaries disagree on the Clang and MSVC minimums — the table above follows cppreference rather than the secondary sources. For the rest of what the standard brought, see our overview of C++23 features.
Use std::cout if you are learning on a school or workplace toolchain you do not control. Use std::println if you control your toolchain and it is current — the compile-time format checking alone is worth the upgrade.
What Your First Program Actually Costs
Here is the part no other Hello World tutorial will tell you: these three near-identical programs behave very differently at build time.
How this was measured
| Setting | Value |
|---|---|
| Date tested | September 2026 |
| Machine | Single-core Linux VM, Ubuntu 24.04 |
| Compilers | GCC 14.2 (g++-14, gcc-14) |
| Flags | -O2, standard as listed per row |
| Iterations | 3 discarded warm-up runs, then mean of 20 |
| Statistic | Mean wall-clock time, including process spawn |
| Not captured | No median, no percentiles, no CPU-frequency control |
| Program | Compile time | Stripped binary | Lines after preprocessing |
|---|---|---|---|
C, printf (-std=c17) | 30 ms | 14,472 bytes | 543 |
C++, std::cout (-std=c++17) | 277 ms | 14,472 bytes | 36,915 |
C++, std::println (-std=c++23) | 2,654 ms | 100,656 bytes | 66,007 |
Reproduce it yourself. The three numbers in each row come from these commands:
# compile time (repeat and average; discard the first few runs)
/usr/bin/time -f "%e" g++-14 -O2 -std=c++17 hello.cpp -o hello
# stripped binary size
g++-14 -O2 -std=c++17 hello.cpp -o hello && strip hello && stat -c%s hello
# lines the compiler actually parses
g++-14 -E -std=c++17 hello.cpp | wc -l
Swap -std=c++17 hello.cpp for -std=c++23 hello23.cpp, or g++-14 for gcc-14 -std=c17 hw_printf.c, for the other two rows.
Three findings, in order of how surprising they are.
The iostream and printf binaries are exactly the same size — 14,472 bytes each. The C++ version is not “fatter”; the stream machinery lives in the shared libstdc++, which the program links against rather than copies. In this dynamically linked GCC build, the cost of <iostream> was paid at compile time and not in the executable. Static linking, LTO or a different standard library would change that.
That compile-time cost is real and it is about 9×. Every one of those 36,915 preprocessed lines is parsed on every build. On a four-line program you will not notice. On a project with four hundred files, this is one of the main reasons C++ builds get expensive as a project grows.
<print> is currently the most expensive of the three to compile, by a wide margin. The formatting machinery it pulls in is header-only, so the work happens in your translation unit — and the resulting binary is seven times larger than the iostream one. The ratio is the durable finding here, not the absolute milliseconds: this was measured on a single-core VM, so your numbers will be lower. The trade is compile-time format checking for a slower build. For code that formats anything more complex than a fixed string, that is usually the right side of the trade.
One thing I expected to find and did not: I looked for an extra static initializer in the iostream binary — the std::ios_base::Init object that older accounts describe — and .init_array was 8 bytes in all three binaries. Modern libstdc++ handles stream initialization inside the library. The folklore is out of date.
Common Errors, in the Compiler’s Own Words
Four failures are worth recognising on sight. These are the actual GCC 14.2 messages, not reconstructions.
Using the pre-standard header. <iostream.h> was never part of standard C++. It was used by pre-standard C++ implementations; standard C++ uses <iostream> and the std namespace. If an old tutorial tells you to include <iostream.h>, replace it with <iostream>.
err1.cpp:1:10: fatal error: iostream.h: No such file or directory
1 | #include <iostream.h>
| ^~~~~~~~~~~~
compilation terminated.
Writing cout without std::. Note that the compiler tells you exactly how to fix it:
err2.cpp: In function 'int main()':
err2.cpp:3:5: error: 'cout' was not declared in this scope; did you mean 'std::cout'?
3 | cout << "Hello, World!\n";
| ^~~~
| std::cout
Declaring void main(). Seen in an enormous amount of old teaching material. It is not C++ and never was:
err3.cpp:2:1: error: '::main' must return 'int'
2 | void main() {
| ^~~~
Forgetting a semicolon. The compiler points at the character after the one you missed, which confuses beginners until they learn to read it that way:
err4.cpp: In function 'int main()':
err4.cpp:3:35: error: expected ';' before 'return'
3 | std::cout << "Hello, World!\n"
| ^
| ;
A Variation Worth Writing Next
Hello World is a one-way conversation. Two more lines make it a two-way one, and introduce std::string and input handling:
// greet.cpp - Hello, World! with a name
#include <iostream>
#include <string>
int main() {
std::cout << "What is your name? ";
std::string name;
if (!std::getline(std::cin, name) || name.empty()) {
name = "World";
}
std::cout << "Hello, " << name << "!\n";
}
Output:
What is your name? Saqib
Hello, Saqib!
The if is the part worth copying into your habits. std::getline can fail — the user presses Ctrl-D, or input is piped from an empty file — and a program that ignores that failure prints a greeting to nobody with an empty name. Checking the result of an input operation is a discipline you will use for the rest of your C++ career. Fed no input at all — piped from an empty file, or Ctrl-D at the prompt — the program falls back cleanly. The prompt and the greeting share a line here because the prompt deliberately has no \n:
What is your name? Hello, World!
A quick way to date a C++ tutorial without reading it: look at the first program. If it includes <iostream.h>, it predates the 1998 standard. If it declares void main(), it was never valid C++ at all. If it opens with using namespace std; and then writes std::cout anyway, it was written by copying rather than by compiling. The version of this page published in 2018 did exactly that — the example declared the namespace directive and then qualified the call regardless. It compiles, it runs, and it teaches a habit you will have to unlearn.
Key Takeaways
- The modern C++ Hello World is four lines:
#include <iostream>,int main(), astd::coutstatement ending in\n, and a closing brace.return 0;is implicit inmainand may be omitted. - Write
std::cout, notusing namespace std;. The qualified form is what production code uses, and learning it first means never unlearning it. End a line of output with\n. Without it your text collides with the shell prompt, which looks like a bug and isn’t one — though a deliberate prompt, as in the input example below, correctly leaves it off.- C++23’s
std::printlndoes the same job in two lines and adds the newline for you — but it needs GCC 14+, Clang 18+ or MSVC 19.37+, and falls over loudly on anything older. In this build,<iostream> cost compile time rather than binary size. Theiostreamandprintfexecutables measured here were byte-for-byte the same size; the C++ build took roughly 9× longer.- Compile with
-Wall -Wextrafrom your very first program. It costs nothing now and catches real bugs later. - Learn to read compiler errors rather than fear them. Every error in the section above names the file, the line, the column and usually the fix.
Frequently Asked Questions
Conclusion
Hello World is the only program you will ever write whose entire purpose is to fail informatively. Everything after this one assumes the toolchain works; this one is how you find out. That is why the errors above matter more than the code — you will meet them again in programs where the cause is not four lines away.
When it runs, the sensible next step is a program that reads input, then one that loops, then one that defines a type of your own. Our complete guide to C++ programming covers that progression in order, and the rest of the C++ tutorials go deeper on each step. If you are curious how the same four lines look elsewhere, our collection of Hello World programs in 300 programming languages is a genuinely entertaining way to spend ten minutes.
What I Could Not Verify
Every program, output block and error message on this page was produced on one machine: a single-core Ubuntu 24.04 VM running GCC 13.3 and GCC 14.2. The Linux commands and the C++23 behaviour were tested there. The macOS and Windows compile commands were not run for this article — they are the standard invocations for Clang and MSVC and are given from documentation, not from a captured session. The <print> availability table is from cppreference’s C++23 support page, checked this session; only the GCC rows were confirmed by compiling. Compile-time figures will differ on your hardware — the ordering and the rough size of the gaps are what should transfer, not the milliseconds.


