Skip to content
VLSI Mentor

C++ Part I · Module 2 · Building and Running C++ Programs

The Structure of a C++ Program

Module 1 was orientation. It taught you what C++ is, why it exists, and where it is used, but it deliberately taught no C++ you could write. That changes here. This chapter looks at the smallest complete C++ program there is — one line long — and accounts for every piece of it. Where does a program start? What does the number at the end actually do? What makes a statement a statement? You will also meet one rule that applies to main and to nothing else in the language, and which surprises people who learn it by accident years later. We will be honest about one more thing: a real program has parts this one does not, and some of those parts cannot be explained properly yet. Those get named rather than hand-waved, with the chapter that makes each one precise.

Foundation12 min readC++Part IFundamentalsProgram Structure

Part I · Module 2 · Chapter 2.1 · The Structure of a C++ Program

1. The Smallest Complete Program

This is a whole C++ program. Nothing is missing from it:

Azvya Education Pvt. Ltd.VLSI Mentor
min1.cpp — a complete program
int main() { return 0; }

It compiles. It runs. It does nothing visible, which is fine — doing nothing visible is a perfectly good thing for a program to do while you are learning what the parts are.

Most tutorials start with a program that prints text. We are not doing that yet, and the reason is practical. A printing program needs an #include line and a stream object, and explaining those properly takes three more chapters. Starting without them means every character on the page above can be explained right now, with nothing deferred.

So: four pieces of punctuation and three words. Let us take them in order.

2. Execution Starts at main

A program needs a place to begin. In C++ that place is a function called main.

You do not call main yourself. When you run the program, the system starts it, some setup happens, and then main is called for you. When main finishes, the program ends.

That gives you the first durable rule:

main is where your program starts and where it ends. Every C++ program that runs on its own has exactly one main.

Two consequences follow, and both come up in practice:

  • Exactly one. Not zero, not two. A program with no main has no starting point, and a program with two has an ambiguous one. Both fail to build, and Chapter 2.7 shows you what each failure looks like.
  • The name is fixed. main is not a convention you could change by renaming it. Main, MAIN and start are different names, and none of them is the starting point.

You will write other functions later — Module 6 is about them properly. They run only when something calls them, directly or indirectly, starting from main.

3. What the Number Means

Look at the two ends of the line:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
int main() { return 0; }
//  ^                ^
//  |                └── the value handed back
//  └── the kind of value main hands back

The int at the front says main hands back a whole number. The return 0; at the end is where it does so.

Hand it back to whom? Not to another part of your program — nothing in your code called main. It goes to whatever started the program: your terminal, a build script, a regression runner, a continuous-integration job.

That number is called the program's exit code or exit status, and the convention is simple and near-universal:

  • 0 means success.
  • Anything else means failure, and the particular non-zero value can say which kind of failure.

This is not decoration. It is how one program tells another whether it worked. A regression script that runs two hundred simulation checks does not read their console output to decide whether they passed — it reads their exit codes.

Here is a program that reports failure:

Azvya Education Pvt. Ltd.VLSI Mentor
exit3.cpp — a complete program that reports failure
int main()
{
    return 3;
}

On a Unix-like shell you can see the code it returned. The shell stores the last program's exit status in $?:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
$ ./exit3
$ echo $?
3

Nothing was printed, and the program still communicated something. That is the point of the exit code: it works when there is nobody watching the screen.

4. Statements, Semicolons and the Block

Between the braces is the body of main — the work it does.

return 0; is a statement: one complete instruction. In C++ a statement ends with a semicolon. The semicolon is not punctuation the way a full stop is in English; it is how the compiler knows one instruction has finished and the next begins.

The braces { and } mark a block: a group of statements treated as one unit. main's body is a block. A block can hold one statement, many, or none.

Spreading the same program over several lines changes nothing:

Azvya Education Pvt. Ltd.VLSI Mentor
min1.cpp, written the way you will actually write it
int main()
{
    return 0;
}

This is the same program as the one-liner in §1. The compiler sees the same sequence of words and punctuation either way. Line breaks and indentation exist for the people reading the code, and the compiler ignores them.

That freedom is worth stating plainly, because it is the reason formatting is a team decision rather than a language rule: the compiler does not care, so you should, and consistently.

One thing that is not free: you cannot split a word. int main is two words; in t main is an error. Whitespace separates things, it does not get inserted into them.

5. The One Rule That Applies Only to main

Here is a program with no return statement at all:

Azvya Education Pvt. Ltd.VLSI Mentor
min2.cpp — a complete program. Note what is missing.
int main()
{
}

It compiles cleanly, with -Wall -Wextra -Wpedantic and no warnings. And when you run it:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
$ ./min2
$ echo $?
0

It returned 0 — the success value — even though nothing in the source says so.

This is a real rule in the C++ standard, and it is special to main. If control reaches the end of main without hitting a return, the effect is the same as return 0;. The language inserts it for you.

6. Comments

Two forms, both ignored entirely by the compiler:

Azvya Education Pvt. Ltd.VLSI Mentor
Both comment forms
int main()
{
    // Everything after two slashes, to the end of the line.

    /* This form starts here
       and runs until the closing marker. */

    return 0;
}

The first form is what you will use almost always. The second is useful when you want to comment out a block temporarily, though it does not nest — a /* inside a /* ... */ does not start a second comment, and the first */ ends the whole thing. That catches people out.

A note on what comments are for, since it shapes everything you write later. A comment that restates the code is noise:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    return 0;    // return zero

A comment that says something the code cannot is valuable:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    return 3;    // 3 = input file could not be opened; see docs/exit-codes.md

The second one records a decision. The first one is a line that can go out of date and tells you nothing while it is still accurate.

7. What a Real Program Adds

Our program is complete but minimal. A program that does something useful has more parts, and it is worth seeing them named now so they are not a surprise:

Azvya Education Pvt. Ltd.VLSI Mentor
A preview — the parts, not the lesson
#include <iostream>          // 1. bring in something defined elsewhere

int cycles_for(int transfers);   // 2. your own function, declared

int main()                       // 3. the starting point
{
    int result = cycles_for(8);  // 4. a variable, and a call
    std::cout << result << '\n'; // 5. output
    return 0;
}

int cycles_for(int transfers)    // 6. your own function, defined
{
    return 3 + transfers * 2;
}

You are not expected to write this yet. Each numbered piece has an owner:

PieceWhat it is, roughlyTaught properly in
#include <iostream>Pulls in code and names written elsewhere2.4, and 2.5 for what it literally does
int cycles_for(int);Tells the compiler a function exists before it is used2.4, Module 6
int main()The starting pointThis chapter
int result = ...A named piece of storage holding a valueModule 3
std::cout << ...Sending a value to the console2.2, 2.8
the function bodyWork packaged under a nameModule 6

Three of those six are provisional right now, and this curriculum will keep saying so rather than letting you assume you understand something you have only seen. When Chapter 2.2 uses std::cout, it will tell you exactly how much of it you are being asked to take on trust and for how long.

8. Mistakes Worth Making Once

Believing main is called by your code. It is not. Nothing in your source calls it. The system starts the program, the runtime does its setup, and main is called from outside your program entirely. This matters later: when Module 7 asks when a static object is initialised, "before main runs" is a meaningful answer, and it only makes sense if you know main is not the first thing that happens.

Thinking the exit code is the printed output. They are completely separate channels. A program can print "all tests passed" and return 1. The script that runs it will believe the 1. Make them agree.

Dropping the semicolon. The compiler will not stop at the end of the line looking for one — it keeps reading, and the error it reports is often on the next line, where the combined text finally stops making sense. Chapter 2.7 covers why the reported line is sometimes one past the real mistake.

Leaving out return 0; and then doing the same in another function. The rule in §5 applies to main alone. Carrying the habit elsewhere produces a function that promises a value and does not deliver one.

9. What You Should Be Able to Say Now

  1. int main() { return 0; } is a complete C++ program.
  2. Execution starts at main. Every runnable program has exactly one, the name is fixed, and your code never calls it.
  3. int before main says it hands back a whole number; return 0; is where it does.
  4. That number is the exit code, read by whatever started the program. 0 means success and any other value means a specific failure.
  5. A statement is one instruction and ends with a semicolon. A block is a group of statements in braces.
  6. Line breaks and indentation are for readers. The compiler ignores them, which is why formatting is a team decision.
  7. If control reaches the end of main without a return, the effect is return 0;. This rule is special to main; in any other value-returning function, falling off the end is undefined behaviour.
  8. Write return 0; anyway, to keep the habit correct everywhere else.
  9. Comments are ignored by the compiler. Write them to record decisions, not to restate the code.

10. Exercises

Exercise 1 — predict the exit code. For each program, say what echo $? prints after running it, and why: (a) int main() { return 0; } (b) int main() { } (c) int main() { return 7; }.

Exercise 2 — one program or two? Are these the same program? Explain what the compiler sees in each case.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
int main() { return 0; }
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
int
main
(
)
{
    return 0;
}

Exercise 3 — spot the dangerous habit. A colleague writes a function that is supposed to return an int and forgets the return. They point out that their main has no return either and works fine. Explain in two sentences why the two cases are not the same.

Exercise 4 — design an exit code. You are writing a tool that checks a register dump against expected values. It can succeed, fail to open the file, or find mismatches. Propose an exit code for each outcome and say why you chose 0 for the one you did.

Exercise 5 — judge the comments. Which of these is worth writing, and why?

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    return 2;    // returns 2
    return 2;    // 2 = mismatch found; the regression script retries on 2 only

Exercise 6 — the missing starting point. Without compiling, predict what happens if a file contains a correct function called start and no main at all. Say which tool reports the problem, and then check your answer against Chapter 1.7 §4 or Chapter 2.7.

11. Summary

  • int main() { return 0; } is a complete program. Everything else is addition.
  • main is the starting point, there is exactly one, the name is fixed, and your code never calls it.
  • The returned number is the exit code, read by whatever started the program. 0 is success; other values name specific failures.
  • Statements end with semicolons; blocks group them in braces. Whitespace and line breaks are for the reader.
  • main may omit its return and still return 0 — the only function in the language that may. Write it anyway.
  • Comments record decisions, not restatements of the code.

You can now read the skeleton of a program and say what each part is for. What the skeleton cannot do is tell you anything — it runs and ends in silence, and a program you cannot observe is a program you cannot learn from. Chapter 2.2 writes the first program that produces output, accounts for every character of the new line that makes it possible, and then builds and runs it so you have an edit-build-run loop of your own.

Standards & specifications

Governing standard
ISO/IEC 14882 (the C++ language standard)(opens ISO/IEC (JTC 1/SC 22/WG 21) in a new tab)

Defines the C++ language and its standard library — the type system and templates, the object model and object lifetime, initialisation and overload resolution, the memory model and the containers, algorithms and utilities the library provides. Like C's standard it is a FAMILY of editions (C++98/03, C++11, C++14, C++17, C++20, C++23) and the editions are NOT interchangeable: a feature this curriculum relies on may be unavailable, differently specified or merely proposed in another edition, so each lesson names the edition its claim depends on. It does not define any foreign-function interface to a hardware description language, nor what a compiler actually emits, nor platform behaviour on real silicon — those are the implementation's and the device's contracts. Working drafts published by WG21 are freely available and are what most engineers read day to day; a draft is not the published standard.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of the C++ Programming curriculum.