Different people have different ideas of what is simple.

— Bjarne Stroustrup

Interesting Things And Helpful Resources


Tag brackets mean look for this file in the directory where all the standard libraries are stored.

#include <iostream>

Double quotes mean the same as tag brackets or the current directory if the specified file is found in it.

#include "main.hpp"


The following line is an example of how kludgey C++ can be:

using namespace std;

I find this command to be awkward. It is cryptic, not part of your train of thought when trying to get something to work and, unfortunately, hardly ever unnecessary. This line simply must be included to activate the correct name space for certain important libraries. There may be others but <iostream> and <string> are definitely some that need this command.

Without it you need something like this.

std::cout<<"This is suboptimal.";

Although this is an annoying requirement because most of the time it is used mechanically in the case shown above, the namespace mechanism is a C++ feature that allows better organization and protection of program elements.

Comment Styling

In C, the comments are this bizarre syntax:

/* This is a classic C style comment. */

In C++ that is acceptable but there is another style that has a starting designator and runs to the end of the line. Like this:

// This is a C++ comment.
x++ // The beginning of this line is not a comment but this is.


For style tips in general, you could do worse than to emulate these guys. (Do they not host it themselves anymore?)

Here’s another.

Variable Types

As with C, all variables must be explicitly declared before using. The point of this relates to C and C++ and their very explicit use of memory management.


Like C, make a variable immutable with the const keyword. Well, a "read-only variable", like the C++ error messages say, is an oxymoron.

This is simple in the simple cases. But there is all kinds of mischief that can arise from this. The most absurd to me is the mutable keyword which can make const declarations, uh, less const.

Type Details

Actually with the Cpp11 auto keyword (not to be confused with the K&R C auto compiler hinting) in some instances, the types of variables can be automatically deduced from context. Some more information and examples.

bool Exclusive to C++!



keywords true or false, or integers 1 or 0


Character or small integer.


signed: -128 to 127 unsigned: 0 to 255

short int (short)

Short Integer.


signed: -32768 to 32767 unsigned: 0 to 65535




signed: -2147483648 to 2147483647 unsigned: 0 to 4294967295

long int (long)

Long integer.


signed: -2147483648 to 2147483647 unsigned: 0 to 4294967295


Floating point number.


+/- 3.4e +/- 38 (\~7 digits)


Double precision float


+/- 1.7e +/- 308 (\~15 digits)

long double

Long double float.


+/- 1.7e +/- 308 (\~15 digits)


Wide character.

2 / 4 bytes

1 wide character

Note that C++ is more strict about type casting that C.

Variable definitions in C generally must be at the beginning of a block whereas in C++ they can be anywhere in the block.

C++ provides a way to get a runtime check of what kind of type a variable is. This is done with the typedef function and is useful when variables can be any of several types or objects.


C enum values are always sized int whereas in C++ they are a distinct type and can have different sized values. This defines a new user type DOW.

enum DOW {Sun,Mon,Tue,Wed,Thu,Fri,Sat};

You can do a lot in the definition. Here the type declares a variable (casual) and sets it.

enum DOW {Sun,Mon,Tue,Wed,Thu,Fri,Sat} casual=Fri;

Some people believe that enums should be named as singular nouns and not plural. Although enums may define a collection of possibilities for ,say, problem_types, the possibility will just be a problem_type when actually used.

Implicit Conversions

  • integer to float = OK

  • char to float = OK

  • float to int = OK (truncated obviously)

  • float to char = silently does the wrong thing


Because memory management is such a focal point of C programming, only char which provides a single non-numeric value is really practical without going into a more elaborate mechanism. In C++ the string class is that more elaborate mechanism. Strings are generally used like this:

#include <string>
using namespace std;
int main () {
  string thestr("Initialization like an object.");
  thestr= "Assignment like a variable.";
  return 0;

Although this example doesn’t do anything, it doesn’t produce an error. Note that because it is a class (string) it can be initialized like a new object as an initialization function parameter. Subsequent redefinitions use the overloaded = operator to simulate the way normal people would expect a programming language to work.

Note that double quotes signify strings and single quotes are characters.

Input And Output

C uses scanf and printf for input and output. C++ can use these but idiomatic C++ programs use a different mechanism not available in C.


These are available from include #iostream. You probably also want to turn on using namespace std; to cut down on trivial scope chatter. These are really not exactly functions but more like named pipes (in the std namespace) which get data sent in and out of them (<< and >> are overloaded operators normally used for bit shifting).

The >> operator is the "extraction" operator and reads input "items" which are expected to be delimited by whitespace (space, newline, tab).

if (fileStream.is_open())
    while (fileStream.good()) {
        string word;
        fileStream >> word;
        // Do something with "word"

Here is a complete output ("insertion" operator) example:

#include <string>
#include <iostream>
using namespace std;
int main () {
  string thestr("String objects can be output like so.");
  cout << thestr << endl;
  return 0;

The cout doesn’t just dump a \n; it also performs cout.flush().

Here are some good notes on C++ IO.

cin and getline

It seems that cin is good for reading space delimited fields one field at a time (or something like that), but it doesn’t read whole lines.

int main() {
    std::string myLine;
    std::cout<<"Enter the whole line: ";
    std::getline(std::cin, myLine);
    std::cout<<"Your line is: "<<myLine<<"\n";
    return 0;


#include <iostream>
#include <iomanip>
int main () {
    std::cout<<std::setw(15)<<"Padded 15"
             <<std::setw(20)<<"Padded 20"<<std::endl;
    return 0; }


#include <iostream>
#include <string>
#include <sstream>

int main () {
    std::string stringifiednumber;
    float mynumber = 0;
    std::cout << "Enter number: ";
    std::getline (std::cin,stringifiednumber);
    std::stringstream(stringifiednumber) >> mynumber;
    std::cout<<"Plus one would be: "<<++mynumber<<"\n";
    return 0;

File Operations

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(){
    string line;
    // Create output stream for writing in append mode.
    ofstream f2write ("input.txt", ios::app);
    if (f2write.is_open()) {
        f2write << "\nThe End.\n";
        cout << "Unable to open file for writing";
    // Create input stream for reading.
    ifstream f2read ("input.txt");
    // The file is opened at ifstream creation.
    if (f2read.is_open()) {
        while ( getline (f2read,line) ){ cout << line << '\n'; }
        cout << "Unable to open file for reading";
    return 0;


Some C++ specific keywords, new and delete, help with memory allocation and deallocation issues.


In C it is good practice to prototype functions (describe their input and output before using them).

Unlike C, in C++ functions can be overloaded. This means that their meaning can be redefined.

Also C++ can use functions inside of structures. This is not common but it hints at the more C++ way of organizing functionality, classes, discussed in the next section.

Unlike C, C++ allows the program to define default values for function arguments.

Incrementing Shortcut Operators

Prefix operators (e.g. ++var) increment the value and then return a reference.

Postfix operators (e.g. var++) create a copy of the variable, increment the value, then return the copied, unincremented value.

Also C++ has += and other such operators as found in Python.

Inline Functions

C++ discourages the use of preprocessor complexity. Instead, the idiomatic C++ way to do preprocessor functions is with the keyword inline.

Control Flow

if ( x>=y ) { dothis();}
else if (x<y) { dothis();}
else { dothis();} // Optional.
int choice=1;
switch (choice) {
    case (0) : cout<<"no"<<endl;  break;
    case (1) : cout<<"yes"<<endl; break;
    default : cout<<"huh?"<<endl;
for (int i=0; i<10; i++) {
for with implicit type casting
#include <cstddef>
for (std::size_t i=0; i<10; i++) {

There is also a newish for more like Python or Bash.

for ( declaration : range ) statement;
while (conditional) { do_stuff(); // Keep it up! }
do { do_stuff(); } while (conditional); // Make sure at least one happens.

Both break, to exit the loop immediately, and continue, to conclude the current loop body execution and go on to the next, are valid.

To get an infinite loop that needs a break to get out of (or not) here are options.

for (;;){... }
while(1){... }


int I=20, *pI;
pI= &I; // Pointer to I is the address location of I.
cout << *pI; // Dereference returning value pointed to by pI.


References are a feature specific to C++ not found in C. Although the subtleties get complex, the greatest utility of references is simply as a way to pass by reference to functions easier. You can still move things around by pointers if you want but references often allow function calls to be less complicated.

  • In Unix terms, I think of pointers as symlinks and references as hard links. The reference is the object accessed differently, not a pointer to an address that may not contain anything.

  • You can also think of a reference as a constant pointer.

  • Pointers are variables that contain memory addresses while references are additional definitions of compiler tracked objects. (The compiler thinks: "Ah, he’s calling x another thing, y, now too.") Of course the compiler can use the same machinery it uses for pointers for this but references can be implemented more efficiently. That’s up to the compiler.

  • References point to objects (whose address a reference shares), while pointers can point to other pointers, ad infinitum.

  • References can (should) not normally be NULL.

  • References can not iterate using pointer arithmetic.

  • Pointers need to be dereferenced with *, or -> for class members, while references can be dereferenced with . like the referent ("automatic indirection").

Simple Demonstration Of References
#include <iostream>
using namespace std;

// Function with reference parameters.
void one2theother(int &from, int &to) { from--; to++; }
// Function with reference parameters returning a reference.
int &add2together(int &a, int &b) {
    int s; int &r2s=s; r2s= a+b; return r2s; }

int main () {
    int var= 10; int var2= 99;
    int &ref2var= var;
    cout << var << endl      // 10
       << ref2var << endl;   // 10
    cout << var << endl      // 11
       << ref2var << endl;   // 11
    cout << var << endl      // 12
       << ref2var << endl;   // 12
    one2theother(var,var2);  // Function using references.
    cout << var << endl      // 11
       << ref2var << endl    // 11
       << var2 << endl;      // 100
    cout << add2together(var,var2) << endl; // 111
    return 0;

Here is a lot of expertise on the topic for those who really need it.


C++ features organization by classes.

Table 1. Special Member Functions

Default constructor




Assignment operator

void operator=(X &src)

Copy constructor

X(X &src)

Printing function

void print(ostream *os)

Example of Using Classes
// cxe- Wed May 12 12:22:10 PDT 2004
// This is a test of using inheritance to create a containable class (or array
// in this example) of heterogenous objects. The goal will be to store 2
// classes in the same array in such a way that they are usable.

#include <string>
#include <iostream>
using namespace std;

class Number {  // This is the base class.
      Number() {}
      virtual void show() { cout << "No base class data!" << endl; }
}; // end class Number

class Roman: public Number {
      Roman operator=(string p) { pretium= p; return *this; }
      void show() { cout << "Roman:" << pretium << endl; }
      string pretium;
}; // end class Roman

class Arabic: public Number {
      Arabic operator=(int v) { value= v; return *this; }
      void show() { cout << "Arabic:" << value << endl; }
      int value;
}; // end class Arabic

int main() {
   Number z; //can't do anything with z
   Arabic a; a= 19;
   Roman  r; r= "XIX";
   cout << "Objects as themselves, no container ----------" << endl;
   z.show(); a.show(); r.show();

   Number n[3]; // Array of base class objects
   n[0]= z; n[1]= a; n[2]= r;
   cout << "Objects in container of baseclass ----------" << endl;
   n[0].show(); n[1].show(); n[2].show();

   Number *p_n[3]; // Array of pointers to Numbers
   p_n[0]= &z; p_n[1]= &a; p_n[2]= &r;
   cout << "Objects in container of baseclass pointers ----------" << endl;
   p_n[0]->show(); p_n[1]->show(); p_n[2]->show();

   return 0;
} // end main

This outputs the following.

Objects as themselves, no container ----------
No base class data!
Objects in container of baseclass ----------
No base class data!
No base class data!
No base class data!
Objects in container of baseclass pointers ----------
No base class data!

Note that the default access is private so by listing them before public, you can save that keyword. I think it’s better to just be explicit though.

Declarations will often need the class namespace. This looks like this.

retVar ClassName::somefunction(int x,int y);


The virtual keyword is confusingly used for different purposes depending on context. Here are two of the uses. There may be more.

  1. A function declared virtual means that an existing overriding function in a derived class is invoked.

  2. An inheritance relationship declared using keyword virtual between classes Derived1 and Derived2 that inherits from class Base means that another class Derived3 that inherits from Derived1 and Derived2 still results in the creation of only one instance of Base during instantiation of type Derived3.

Member Initialization Lists

In class definitions the constructor can have a list of members with their correct initial values defined. These are placed after the constructor name and parameters, followed by a : and before the body of the constructor. The following are very similar. The first is preferred since it avoids unnecessary copies.

MyClass(int some_init_args):member1(5){}
MyClass(int some_init_args){member1=5}
Example of Member Initialization Lists
#include <iostream>
class Parent {
    Parent( int x ) {
        std::cout << "Parent's constructor"
        << " called with " << x << std::endl;

class Derived: public Parent {
    Derived() : Parent( 10 ) { // With "Member Initialization List".
        std::cout << "Derived's constructor" << std::endl;

class Strclass {
    Strclass() : thestr("This is the init string.") {
        std::cout << thestr << std::endl;
    std::string thestr;

int main() {
    Derived a_derived_instance;
    Strclass somesc;


Recovering from errors in C is done by explicitly planning for every specific erroneous condition. In C++ there is a system of "exceptions" where (specifically) unanticipated errors can be treated reasonably.

While it is critical to understand exceptions I personally have some misgivings about them which are well documented in my Python notes. Without going into details here, I’ll sum up my personal opinion about C++ exceptions by quoting the Google C++ Style Guide which simply says, "We do not use C++ exceptions."

Here is a rough idea of how C++ exceptions work.

Example Of Exception Use
#include <iostream>
using namespace std;

void thefunction() { throw 99; }

int main (int argc, char *argv[]) {
    try {
        if (argc > 1){ thefunction();}
        else { throw '?';}   }
    catch(int e) {  // The catch is chosen based on its type.
        cout << "Exception number " << e << " has occured." << endl;
    catch (...) {  // If the type sent by throw is not defined, go here.
        cout << "Unknown exception has occured." << endl;
    return 0;

When this code is run with arguments it returns:

Exception number 99 has occured.

When this code is run without arguments it returns:

Unknown exception has occured.

Note that the catch statement is chosen based on the type specified by the throw command. In this simple example, this is not remarkable, but when defining your own types with classes, this mechanism can be very useful in organizing code to react to errors arising from different causes.

There are much fancier ways to use exceptions. You can define your own by inheriting standard exceptions. You can also catch and handle standard exceptions your own way. They can be nested such that the inner exception passes the information through to the outer ones.


template <typename T>
T functionName (T  parameter1,T  parameter2,...) { /* Function template. */ }

template <typename T1, typename T2>
T2 functionName (T1  parameter1,T2  parameter2,...) { /* Multiple types. */ }
template <class T>
class Number
{ private: T value; };

IntArray::IntArray(){ /* Normal constructor. */ }

template<class Type>
Array<Type>::Array(){ /* With template. */ }

Standard Template Library

The near universal detest for STL in game development makes each studio’s code a silo of private libraries, which is unfortunate.

You don’t use STL where you need max performance, but performance isn’t the top priority for most code, even in games.

I don’t like STL much and rarely use it, but I do really like standards. The library situation with C++ is really a shame.

#ID_AA_Carmack (2014-04-05)
— John Carmack

Both C and C++ are very spartan languages and in order to do anything useful in either you pretty much need to write some tools to manage simple flexible data structures. This has been thought out in C++ with the Standard Template Library or STL.

STL provides templates that allow programs to easily create simple but powerful data structures for all kinds of pragmatic uses. This is the kind of stuff that higher level languages like Javascript and Python take for granted.

  • deque

  • list

  • map

  • set

  • string

  • vector

Container Adaptors
  • priority_queue

  • queue

  • stack


The following sample program shows the basic STL container usage with a "vector" template.

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> V1; // Define a vector of integers.
    V1.push_back(9); V1.push_back(6); V1.push_back(3); // Load vector.
    for (int i= 0; i<V1.size(); i++) { cout << V1[i] << endl; } // Display values.
    vector<int>::size_type v_st= V1.max_size(); // Note namespace to use size_type.
    cout << "Max number of elements in a Vector<int>: " << v_st << endl;

Reserved Keywords

asm, auto, bool, break, case, catch, char, class, const, const_cast,
continue, default, delete, do, double, dynamic_cast, else, enum,
explicit, export, extern, false, float, for, friend, goto, if, inline,
int, long, mutable, namespace, new, operator, private, protected,
public, register, reinterpret_cast, return, short, signed, sizeof,
static, static_cast, struct, switch, template, this, throw, true, try,
typedef, typeid, typename, union, unsigned, using, virtual, void,
volatile, wchar_t, while


Fancier math. Trig, logs, exp, sqrt, ceil, floor, abs. And wacky stuff like isnan.

#include <cmath>
M_PI // Is pi.
std::pow(base,exponent) // Exponents.
NAN // Is constant.


Newish C++ has a civilized library for random number generation. To use this fine library, I needed to compile with -std=gnu++11.

#include <random>
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(0,255);
int rand_red_value= distribution(generator);

This library seems pretty comprehensive. It features different PRNG engines and a bunch of distributions. See the official documentation for details.

Another way I’ve seen is something like this.

#include <time.h>
#include <cstdlib>
int main() {
int target= rand()%100; // 0-99
std::cout << target << std::endl;
return 0;}

Eigen Library Matrix Operations

Examples of working with Eigen matrices
VectorXd my_vector(2);     // Vertical vector of two elements.
my_vector << 10, 20;       // Comma initializer sets coefficients.
cout << my_vector << endl; // cout prints the vector

MatrixXd my_matrix(2,2);   // Initialize Matrix with 2x2 dimensions.
my_matrix << 1, 2,
             3, 4;         // Set matrix to contain [[1,2],[3,4]].
cout << my_matrix << endl; // cout prints a matrix

my_matrix(1,0) = 11;       // Access by position. 2nd row, 1st column.
my_matrix(1,1) = 12;       // 2nd row, 2nd column
my_matrix.row(i) = my_matrix2.col(i); // Get/set row/col vector.

MatrixXd x
x.setZero(rows, cols);     // Fill with zeros. Also a `setOnes()`.
x.setConstant(rows, cols, value); // Fill with value.
x.setRandom(rows, cols);   // Random values.

MatrixXd my_matrix_t = my_matrix.transpose(); // Transpose.
MatrixXd my_matrix_i = my_matrix.inverse();   // Inverse.
MatrixXd my_mtimesv= my_matrix * my_vector;   // Matrix multiplication.


Here’s a very simple Makefile that can be used on very simple C++ programming tasks.

ALLSRCS:= $(wildcard *.cc)
.PHONY:all clean
all: $(ALLEXEC)
%: %.cc
    g++ -o $@ $<
    rm $(ALLEXEC)


Wondering what the heck is taking so long in your program? You can get hints about what your program spends its time doing.

Do this
    sudo apt-get install linux-tools
    sudo bash -c "echo 0 > /proc/sys/kernel/kptr_restrict"
    perf record ./yourprog --your-opts
    perf report
Get a nice report like this
 18.28%  yourprog  yourprog       [.] Plist::querypoint()                    ▒
 13.85%  yourprog  yourprog       [.] shallowanglecull(Llist*, Tlist*, float,▒
  8.70%  yourprog  yourprog       [.] Llist::querypointA()                   ◆
  7.00%  yourprog  yourprog       [.] Llist::querypointB()                   ▒
  6.73%  yourprog  yourprog       [.] Vector::compareto(Vector)              ▒
  5.76%  yourprog  yourprog       [.] searchlinelist(Plist*, Plist*, Llist*) ▒
  5.69%  yourprog  yourprog       [.] operator==(Vector, Vector)             ▒
  5.55%  yourprog  yourprog       [.] Vector::~Vector()                      ▒
  3.92%  yourprog  yourprog       [.] Tlist::BBinterfere(Llist*)             ▒
  3.59%  yourprog  yourprog       [.] searchtrilist(Plist*, Plist*, Plist*, T▒
  2.96%  yourprog  yourprog       [.] Tlist::querylink()                     ▒
  2.88%  yourprog  yourprog       [.] Llist::queryA()                        ▒
  2.26%  yourprog  yourprog       [.] BBinthelper(float, float, float, float,▒
  1.89%  yourprog  yourprog       [.] Vector::gg_valX()                      ▒
  1.25%  yourprog  yourprog       [.] Llist::querylink()                     ▒
  0.92%  yourprog  yourprog       [.] Tlist::querypointC()                   ▒
  0.91%  yourprog  yourprog       [.] find_matching_pnum(unsigned int, Plist*▒
  0.90%  yourprog  yourprog       [.] Vector::Vector()                       ▒

Or if that isn’t good enough check out gprof.

Actually this hack is quite clever too. See the other suggestions there too (e.g. Valgrind).

Resources For Optimizing