Skip to main content

Hello World

Choosing a Compiler

There are many C++ compilers.

  1. GNU compiler collection (GCC): The standard C/C++ compiler provided on most Linux systems. Linux-only.
  2. Clang: Clang provides various extensions that can be used to build custom compiler add-ons. Cross-platform. Standard on Mac.
  3. Microsoft Visual C++ (MSVC): The standard C/C++ compiler for Windows.
  4. Intel Compiler: Sometimes used. Optimizations for intel products.
  5. MinGW: Like gcc, except works on Windows.

Generally, we prioritize compiling for Linux systems. This means we typically focus on gcc and occasionally clang. Clang is a more modern compiler with many advanced features and better warnings and error messages. However, we generally focus on gcc.

Introduction

In this example, we will demonstrate how print text to a terminal. One of the main use of printing is for debugging. Tools such as Google Logger, are used to make print statements to help determine where a program crashes, without having to use an expensive debugger all the time.

Setup

These tutorials are meant to be worked through inside the tutorial Dev Container, which gives you a ready-made C++ environment (compiler, CMake, debugger, MPI, Boost, spack, cpplint, and the clangd language server) with zero local setup beyond Docker and an editor. See the Dev Containers overview for background.

Prerequisites:

Clone the tutorial and open it in the container:

git clone https://github.com/grc-iit/grc-tutorial.git
cd grc-tutorial
code .

Then open the command palette (Ctrl+Shift+P / Cmd+Shift+P) and run "Dev Containers: Reopen in Container". VS Code builds the image, installs the C++ extensions inside the container, and reopens the project there. The container is defined in the tutorial's .devcontainer/ directory.

Once you are inside the container, the tutorial code is at the workspace root and the GRC_TUTORIAL environment variable is already defined for you (the Dev Container sets it to the workspace folder), so the cd ${GRC_TUTORIAL}/cpp/... commands in the following pages just work — no setup needed.

note

Docker does not save state outside your workspace. Files you create inside the mounted project directory are preserved on your host, but changes elsewhere in the container are lost when it is rebuilt.

Go to the tutorial:

cd ${GRC_TUTORIAL}/cpp/01-cpp-hello-world

C++ Source File

Below is the code in hello_world.cc.

#include <stdio.h>
#include <iostream>

int main() {
printf("Hello world 0\n");
std::cout << "hello world 1" << std::endl;
return 0;
}

We will describe this step-by-step.

C++ Header Files

#include <stdio.h>
#include <iostream>

#include is used to instruct the C++ compiler where to find header files. In our case, the header files being included are "stdio.h" and "iostream". Header files typically contain the definitions of functions. They have the same syntax as a source file, but they don't typically have as much code logic.

To find header files, compilers will search a number of places. For example, "/usr/include" will typically contain "stdio.h" and "/usr/include/c++" may contain iostream. These paths are subject to change depending on the gcc version and OS.

In our case, "stdio.h" is where printf is defined, and "iostream" is where std::cout is defined.

Program start

int main() {
// code here...
}

The main function is required in order to execute a C++ program. When you launch a program, the main function is where the code execution begins.

Console output

printf("Hello world 0\n");
std::cout << "hello world 1" << std::endl;
  1. Text is always in double quotes ""
  2. "\n" in "Hello world 0" means "new line". Analogous to hitting the Enter key on your keyboard in a text editor.
  3. std::cout uses left shift operator (<<) to print to console
  4. std::endl writes '\n' and also flushes the output buffer
  5. printf takes the text as a function parameter

Both printf and cout are valid ways of printing. Typically cout is preferred in C++ programs, but you'll likely see both in example programs.

Program return

int main() {
// code here...
return 0;
}

Main returns an integer "int". This indicates the success or failure of a program. Generally, a return value of "0" indicates the program succeeded. Any other value indicates a failure and the reason for failure.

Building

We will build this code manually using gcc. In general, building things manually is a bad idea. Build tools (CMake nowadays for C/C++) automate much of the process. However, knowing how the compiler works is helpful.

Here we use gcc to compile the program "hello_world.cc":

g++ hello_world.cc -o hello_world

This produces an executable file called hello_world in the current directory.

Running the Executable

To run the program, give the path to the executable. The leading ./ tells the shell to look for the program in the current directory:

./hello_world

The expected output is:

Hello world 0
hello world 1

The first line is printed by printf and the second by std::cout.

Checking the Return Code

Every program returns an integer exit code when it finishes. Our main ends with return 0, and by convention 0 means success — any non-zero value signals some kind of failure. On Linux, the shell stores the exit code of the most recent command in $?, so you can inspect it with:

echo $?

The output will be:

0

which is exactly the value we returned from main.