Hello and welcome. After the little intermezzo about text editors, we’re getting back into C++ with this post, following the path of my primary programming language.

This time it’s about the basic framework you’ll find in every C++ program.

Anatomy of a C++ program

Maybe you still remember our first “Hello World!” together. Now I’d like to take a closer look at that together with you. While it can’t output anything more than the string “Hello World!”, it has the fundamental components of a C++ program.

The goal is to understand what happens in each line and which lines are mandatory for a working program.

// Preprocessor Directive
#include <iostream>

// The Body - Start of the Program
// main() Function
int main()
{
    // Output
    std::cout << "Hello World!" << std::endl;

    // Return Value
    return 0;
}

// listing1: HelloWorld.cpp

You can also find the source code in my Gitlab repository for this series of blog posts.

Preprocessor Directive

You can divide the source code into two functional parts. The first part are the instructions to the preprocessor. You can recognize them by the preceding #. They are followed by the body of the program starting with main().

As you probably guessed correctly, the preprocessor is a tool that runs before the actual compilation. Preprocessor statements are commands to the preprocessor and always start with the hash character #.

No, a #hashtag is something completely different!

The command #include <filename> tells the preprocessor to take the contents of the file, in our case <iostream>, and insert it into the line. <iostream>is a header file from the C++ Standard Library that allows the use of, for example, std::cout. In other words, the compiler understands std::cout only after the preprocessor has included the definition of std::cout in the source code.

The name of the file to be added is enclosed in < > brackets for files from standard libraries. However, if you want to include your own files, the name with relative file path is written in " ".

#include "../relative/path/filename"

// listing2: include own header files

The body - beginning of the program

After the preprocessor statements follows the body of the program. The body consists of your functions and is characterized by the main() function. This marks the beginning of each program. This means that the execution of each source code starts at this point. No matter how many functions you write before it.

The C++ Core Guidelines specify as a standard that the main() function is preceded by int. int stands for Integer and denotes the data type of the Return Value of the function.

In some C++ applications you will also find another variant of the main() function (see listing3).

int main (int argc, char* argv[])
{
    return 0;
}

// listing3: main() function parameters

This also conforms to the standard. Here only two parameters are passed in the brackets. With the help of the two arguments you can enable the user of your program to start the application with additional Command Line commands.

$ yourProgramm --MakeThis --DoThat

// listing4: calling an executable with arguments

With this you tell the operating system to open yourProgram and to pass the two parameters MakeThis and ToThis to the main(int argc, char* argv[]).

Back to our code example from listing1. After the declaration of the main() function follows the definition, introduced by a curly bracket {.

cout stands for console out and is the instruction to output the string Hello World to the console. std::cout is a function from the C++ Standard Library and uses its Namespace std.

The data type of std::cout is a stream. And you see in this line how the text Hello World is inserted into this stream with the operator <<. The std::endl statement ends a line. You can think of it as a Carriage Return of the good old analog typewriter, jumping to the beginning of the line on the text page. Keep in mind that you have to insert each entity into a stream one by one using the << operator.

You must have noticed that the lines inside the main() function end with a semicolon ;. The compiler needs these characters to know that your statement ends here. If you forget the semicolon in a statement of a function, your program will not compile without errors.

Return Value

We have just seen that the main() function has an integer number as Return Value. The value is returned to the operating system and serves as a status for whether a program was terminated properly or whether an error terminated the program unintentionally.

Normally the value 0 is used for successful execution and -1 as error indicator. Since the return value corresponds to the integer data type, you can use any integer. This gives you the flexibility to return many different states of success or failure.

In many cases an application is called by another application. The two are then in a Parent-Child__ relationship. The Return Value indicates to the _Parent application whether the Child application has successfully completed its task.

It is also important to know that C++ is case-sensitive. This means that upper and lower case are recognized and evaluated differently. Therefore the compiler will surely give you errors if you write Int instead of int or Std::Cout instead of std::cout.

Comments

So, now we have discussed all lines of the source code… but wait, what about the ones that start with // and are followed by text in spoken language?

These are comments.

Comments are ignored by the compiler during the build process and do not affect the output of the program. So they are not necessary for a fully working application. However, you can use them to add notes or explanations to the appropriate parts of your code. And so that others can understand what you mean, you write a comment in a language that is naturally readable by humans.

C++ supports two types of comments.

// This is a comment; the compiler will ignore it

/* This is a comment
and it spans two lines */

// listing4: comment styles

// marks the beginning of a comment, which is valid until the end of the line. If you want to write longer text that goes beyond one line, you have to interrupt at a suitable place and continue writing on the following line again starting with //.

Alternatively, you can use the second type of comments. You start your text with /* and everything following is commented out. Even beyond line endings. The comment is closed by */.

It may seem strange to explain your code, but the larger a program gets or the larger the number of programmers involved working on a particular module, the more important it is to write code that is easy to understand. Comments help you document what is being done and why it is being done in this way.

But you should consider the use of comments carefully, because the clarity and understandability of your source code may suffer.

Add comments that explain how complicated algorithms and complex parts of your program work. Write in a simple, understandable style. But don’t repeat yourself or describe the obvious.

Comments are not meant to save unnecessarily complicated and incomprehensible code. Rather, they are a useful addition. So you are not absolved from writing good code.

And don’t forget to update your comments when you make changes.

The Namespace

I just mentioned before: the reason why std::cout was used is that the stream class cout is in the namespace std.

But what does this mean?

Imagine cout was a name that would be commonly used by other developers for their functions. You have included two libraries in your program and both contain a function with this name. How does the compiler now know which of the two you want to use? This leads to a conflict and of course the compilation fails.

Exactly for this case a Namespace is useful.

With namespaces you can name parts of your code and avoid such conflicts. By calling std::cout you instruct the compiler to use a unique cout available in the std namespace.

Many people find it too cumbersome to constantly write the namespace specifier when repeatedly accessing this or other functions of a library with namespace. Therefore you can also make the namespace known at the beginning of the body of your program.

// Preprocessor Directive
#include <iostream>

// Body
// namespace
using namespace std;

// main() function with parameters
int main(int argc, char* argv[])
{
    // Output
    cout << "Hello World!" << endl;

    // Return Value
    return 0;
}

//  listing5: namespace

In listing5 the compiler is told that we want to use the namespace std for classes and functions from the C++ Standard Library. Namespaces are known by the preprocessor statement, as are functions. Now you don’t need to add the namespace every time you use std::cout or std::endl.

This should stick

Whew! That’s a lot of stuff we’ve talked about. But don’t stress about having to remember everything right away. Some things were just mentioned and we’ll look at them in more detail another time.

In any case, this is what you should take with you from this entry:

  • A C++ program consists of the Preprocessor Directives and the Body.
  • The body contains the main() function and thus the entry into the program flow.
  • The main() function should always return an integer as status message
  • C++ is case-sensitive

Furthermore, you now have an idea of what a Namespace is, know the difference between a //, as well as /* comment and know how to output a text to the console.

I wish you maximum success!


Sources

  • [1] B. Stroustrup, A Tour of C++. Pearson Education, 2. Auflage, 29. Juni 2018.
  • [2] B. Stroustrup, Programming: Principles and Practice Using C++. Addison Wesley, 2. Auflage, 15. Mai 2014.
  • [3] U. Breymann, Der C++ Programmierer. C++ lernen – professionell anwenden – Lösungen nutzen. Aktuell zu C++17. München: Carl Hanser Verlag GmbH & Co. KG; 5. Auflage, 6. November 2017