Articles & Books

Data-Oriented Design and Avoiding the C++ Object-Oriented Programming Zimmer Frame -- Leigh Johnston

An article about the increasing importance of data-oriented design within the context of C++.

Data-Oriented Design and Avoiding the C++ Object-Oriented Programming Zimmer Frame

by Leigh Johnston

From the article:

Object-oriented programming, OOP, or more importantly object-oriented design (OOD) has been the workhorse of software engineering for the past three decades but times are changing: data-oriented design is the new old kid on the block.

Preprocessing Phase for C++17's Searchers--Bartlomiej Filipek

Searchers objects.

Preprocessing Phase for C++17's Searchers

by Bartlomiej Filipek

From the article:

Searchers from C++17 are a new way to perform efficient pattern lookups. The new standard offers three searchers: default_searcher , boyer_moore_searcher and boyer_moore_horspool_searcher. The last two implements algorithms that require some additional preprocessing for the input pattern. Is there a chance to separate preprocessing time from the search time?

Spaceship Operator--Simon Brand

The future?

Spaceship Operator

by Simon Brand

From the article:

You write a class. It has a bunch of member data. At some point, you realise that you need to be able to compare objects of this type. You sigh and resign yourself to writing six operator overloads for every type of comparison you need to make. Afterwards your fingers ache and your previously clean code is lost in a sea of functions which do essentially the same thing. If this sounds familiar, then C++20’s spaceship operator is for you. This post will look at how the spaceship operator allows you to describe the strength of relations, write your own overloads, have them be automatically generated, and how correct, efficient two-way comparisons are automatically rewritten to use them...

How to Design Early Returns in C++ (Based on Procedural Programming)--Jonathan Boccara

What do you think?

How to Design Early Returns in C++ (Based on Procedural Programming)

by Jonathan Boccara

From the article:

Travelling back from ACCU conference a couple of weeks ago, one of the insights that I’ve brought back with me is from Kevlin Henney’s talk Procedural Programming: It’s Back? It Never Went Away. It’s surprisingly simple but surprisingly insightful, and it has to do with early return statements...

“Modern C++” != “New(est) Standard”--Arne Mertz

What do you think?

“Modern C++” != “New(est) Standard”

by Arne Mertz

From the article:

The term “Modern C++” is often used interchangeably with “Code using the new C++ standard”. Here, “new” may be anything from C++11 to C++17 or even whatever is available of C++20 right now. I think that modern C++ is more and something different than just adding that -std=c++17 flag.

Dependency Management for C++ (2) -- Hans Klabbers

Although I didn’t post anything lately, don’t worry – I’m still working on a proposal for dependency management.

Dependency Management for C++ (2)

by Hans Klabbers

From the article:

I arrived at the conclusion that not only dependency management needs to be taken into account and standardised. Also building software with the defined dependencies need to be taken into account when creating a standard for dependency management.

Quick Q: What are copy elision and return value optimization?

Quick A: they are common optimizations that a compiler can do behind the scenes to avoid copying in certain cases.

Recently on SO:

What are copy elision and return value optimization?

Copy elision is an optimization implemented by most compilers to prevent extra (potentially expensive) copies in certain situations. It makes returning by value or pass-by-value feasible in practice (restrictions apply).

It's the only form of optimization that elides (ha!) the as-if rule - copy elision can be applied even if copying/moving the object has side-effects.

The following example taken from Wikipedia:

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C();
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f();
}

Depending on the compiler & settings, the following outputs are all valid:

Hello World!
A copy was made.
A copy was made.
Hello World!
A copy was made.
Hello World!

This also means fewer objects can be created, so you also can't rely on a specific number of destructors being called. You shouldn't have critical logic inside copy/move-constructors or destructors, as you can't rely on them being called.

If a call to a copy or move constructor is elided, that constructor must still exist and must be accessible. This ensures that copy elision does not allow copying objects which are not normally copyable, e.g. because they have a private or deleted copy/move constructor.

C++17: As of C++17, Copy Elision is guaranteed when an object is returned directly:

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C(); //Definitely performs copy elision
}
C g() {
    C c;
    return c; //Maybe performs copy elision
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f(); //Copy constructor isn't called
}