Yet Another Coder

5 most interesting talks from Meeting C++ 2014

Meeting C++ 2014 conference was held in Berlin in December, and with support from Tableau I was able to attend it. The conference had 3 parallel tracks of talks, so I’ve seen a third of the talks at the time, plus I watched a few more recordings afterwards based on the talk descriptions. I think by now all the videos are published on this Youtube channel, you can also find a list of talks with short abstracts on the conference’s website. The conference was overall well-organized, and audio/video are high-quality.

Below is the list of the 5 most interesting talks from this conference, in my opinion. Most talks have the Youtube video embedded in their description, but for some talks I provide the link to the Youtube video separately.

1. “Plain threads are the ‘GOTO’ of today’s computing” by Hartmut Kaiser.

Maybe I liked it because it is so relevant to the performance areas I’m working on. The talk discusses important abstractions for describing parallelism in C++ code, including an overview of the proposed primitives for C++17, and is based on the open-source HPX runtime work.

 

2. “The Evolving Search for Effective C++” by Scott Meyers.

I especially recommend watching the part from approximately minute 14 till minute 60, where Scott describes the process of writing the Item 42 “emplace vs insert” guideline for his latest book “Effective Modern C++”. The rest of the talk is less technical, Scott gives a historical overview of his publications and talks about writing effective guidelines in general.

3. “The C++ Memory Model” by Valentin Ziegler.

Good quality overview of the Standard with regards to modern C++ memory model, multithreading, data races, atomics, memory ordering. But if you know all that, and can explain the SC-DRF model and how the Standard defines “synchronizes-with” and “happens-before”, then you don’t need to watch it :)

Read the rest of this entry »

C++ curiosities: move semantics is not about moving

C++ move semantics is not about moving, but about keeping as many things as possible where they already are. Yes, at a very high level of abstraction one can say that move semantics is about “moving ownership” of a resource from on object to another. But performance benefits of move semantics do not come from these high levels of abstraction, they come from the very earthly fact that a move operation usually needs to touch fewer bytes in memory than a copy operation. (If you’re new to C++ move semantics you might like to know that std::move isn’t about moving things either.)

Perhaps, a good analogy for explaining what move semantics moves and what it doesn’t move is the process of selling/buying some large property. Let’s say you need a skyscraper. And you know a guy, who sells a skyscraper which fits your needs exactly. It’s an existing building, it has a certain known address, and it’s huge. You want to buy it, but, alas, the legal system in the city (you live in the PlusPlusCity98) is a bit quirky: the ownership belongs to the person who constructed the skyscraper and the ownership is non-transferable. Then the only option you have (since you want exactly the same building, and have a distaste for bribing the city officials):

  1. Buy a piece of land nearby.
  2. Ask the owner of the skyscraper to give you the blueprints of the building, and to give you access inside to see every floor and office in the skyscraper.
  3. Construct a full replica of the existing skyscraper on your land.
  4. Inform the owner when the replica is done.
  5. The owner tears the original skyscraper down to sell the land underneath.

Technically, you could say that the skyscraper was moved: its address has changed, but not its internal structure. But this is in fact analogous to C++ copy semantics, not move semantics. This happens in C++98 when you pass a vector<T> by value into a function. Even if the original vector was a “temporary” value, it can not legally “sell” its data to another vector, that data has to be copied byte by byte to a new location.
Read the rest of this entry »

Open code review: Catch

This is one of the “open code review” posts, where I publish my notes after looking through and playing with one of the open source C++ projects. My main goal here is to become a better coder by learning from the experience of other developers, and my secondary goal is to build a mental map of the tools and frameworks available “out there” to not reinvent the proverbial wheel, should I ever need one. The blog post expresses my personal opinion, not affiliated, endorsed, sponsored, etc. I am not arguing for or against the usage of any specific open source library. I will be grateful if you take time to point out any misunderstanding I might have.

Today I looked at philsquared/Catch, “a multi-paradigm automated test framework for C++ and Objective-C (and, maybe, C)”.

Actually, it was long on my list of “to-read” projects, since the first time I’ve heard of it was at the “Meeting C++” conference in December ’14, where Phil Nash, its author, talked about it.

So, why bother about this “yet another” test framework? Catch dedicates a page to the answer, but here’s what caught my attention:

  • extreme simplicity and minimalism of the design (you need to learn very few things to start writing Catch tests);
  • plain text snippets as “first-class” citizens in test names and descriptions (so the tests look like a spec, and test assertions give richer description of the failed requirement);
  • an inventive way to get rid of setup code duplication via the mechanism of “sections” (saves you some coding, see below an example of how sections work).

Here’s how a trivial test in Catch looks like, from its tutorial:

  #define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
  #include "catch.hpp"

  unsigned int Factorial(unsigned int number) {
    return number <= 1 ? number : Factorial(number - 1)*number;
  }

  TEST_CASE("Factorials are computed", "[factorial]") {
    REQUIRE(Factorial(1) == 1);
    REQUIRE(Factorial(2) == 2);
    REQUIRE(Factorial(3) == 6);
    REQUIRE(Factorial(10) == 3628800);
  }

 

And here’s my somewhat unorthodox demo of Catch “sections”. I’m trying to illustrate the mechanism of the section tree traversal. This is not a test at all, I’m using Catch sections here to print 4 lines from Shakespeare which share some of their first few words starting with “Thou shalt…” :) For a more practical example see the vector tests in the Catch tutorial.

  #define CATCH_CONFIG_MAIN
  #include "catch.hpp"

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

  // Catch "sections" are "forks" in the test execution tree.
  // A test run traverses all possible paths to the leaves.
  // This test case produces 4 strings by traversing 4 paths. 
  TEST_CASE("4 lines from Shakespeare")
  {
    cout << "Thou shalt ";  // http://www.rhymezone.com/r/ss.cgi?q=thou+shalt
    
    SECTION("...not")
    {
      cout << "not ";
      
      SECTION("")
        cout << "stir a foot to seek a foe. (Romeo and Juliet: I, i)" << endl;
      
      SECTION("")
        cout << "sigh, nor hold thy stumps to heaven, (Titus Andronicus: III, ii)" << endl;
    }

    SECTION("")
      cout << "remain here, whether thou wilt or no. (A Midsummer Night's Dream: III, i)" << endl;
    
    SECTION("")
      cout << "continue two and forty hours, (Romeo and Juliet: IV, i)" << endl;
  }

  // Test output:

  //Thou shalt not stir a foot to seek a foe. (Romeo and Juliet: I, i)
  //Thou shalt not sigh, nor hold thy stumps to heaven, (Titus Andronicus: III, ii)
  //Thou shalt remain here, whether thou wilt or no. (A Midsummer Night's Dream: III, i)
  //Thou shalt continue two and forty hours, (Romeo and Juliet: IV, i)
  //===============================================================================
  //test cases: 1 | 1 passed
  //assertions: - none -

Read the rest of this entry »

C++ curiosities: std::move that doesn’t move

Despite its name, std::move doesn’t move anything. std::move is no more than a type cast. It has 2 major purposes in life: to return an “rvalue reference” to its argument and to mislead people into thinking it does more than that. In fact, you can call the bluff by calling static_cast<T&&> explicitly instead of std::move and observe all move operations still working to the same effect:

  #include <iostream>
  using namespace std;

  struct A 
  {
    A(){};
    A(A&&) { cout << "I'm so moved!" << endl; };
  };

  int main() 
  {
    A a;
    A aa(static_cast<A&&>(a)); // prints "I'm so moved!"
  }

Why does it matter? Because developers tend to forget about the fact, and treat calls to std::move as some kind of reset() method on the object, and that can lead to defects and fragile code.
Read the rest of this entry »

Open code review: g3log

This is one of the “open code review” posts, where I publish my notes after looking through and playing with one of the open source C++ projects. My main goal here is to become a better coder by learning from the experience of other developers, and my secondary goal is to build a mental map of the tools and frameworks available “out there” to not reinvent the proverbial wheel, should I ever need one. The blog post expresses my personal opinion, not affiliated, endorsed, sponsored, etc. I am not arguing for or against the usage of any specific open source library. I will be grateful if you take time to point out any misunderstanding I might have.

Today I looked into KjellKod/g3log, an asynchronous logger “with dynamic sinks”.

g3log was inspired by Google’s glog library, but, while it feels similar API-wise, it fixes a significant flaw in glog: namely, g3log is asynchronous. Log requests in g3log are put into a queue and flushed to disk by a background thread. This alone makes the library much more attractive than glog, in my opinion. Typically, people write in C++ because they want performance, and blocking disk IO calls in the middle of some intensive computation just do not feel right.

You can find more details about the logger and the sample usage on the project page or in Kjell’s blog. Here is a quick example, the syntax is quite straightforward:

LOG(INFO) << "streaming API is as easy as ABC or " << 123;
LOGF(WARNING, "Printf-style syntax is also %s", "available");

int less = 1;
int more = 2;
LOG_IF(INFO, (less < more)) << "If [true], then this text will be logged";
// or with printf-like syntax
LOGF_IF(INFO, (less < more), "if %d<%d then this text will be logged", less, more);

Read the rest of this entry »