Articles & Books

Memory management of C libraries in C++ -- Kevin Dungs

In the "better C than C" department:

Memory management of C libraries in C++

by Kevin Dungs

From the article:

Today I had some time to play around with libgit2, an excellent C-library for Git. But since I was thinking about using it together with the freshly released Proxygen, the fast HTTP-framework from Facebook, I wanted to use the library functions from C++ from the start.

This was a perfect opportunity to play around with C++ memory management objects in the context of a C-library...

Overload 124 is now available

overload-124.PNGOverload 124 is now available. It contains the following C++-related articles, and more:

 

Overload 124

Designing Observers in C++11

The observer pattern is over two decades old. Alan Griffiths fits a venerable design pattern into a contemporary context.

Order Notation in Practice

What does complexity measurement mean? Roger Orr reminds us of the academic definition and looks at some real life situations... std::sort is faster than qsort which can come as a surprise to those who assume C is always faster than C++.

Common reasons of using namespaces in C++ projects -- CoderGears Team

CoderGears team draws some conclusions on how namespaces are used in C++ projects:

Common reasons of using namespaces in C++ projects

by CodeGears Team

From the article:

Namespaces in C++ are most often used to avoid naming collisions. Although namespaces are used extensively in recent C++ code, most older code does not use this facility. After exploring the source code of many C++ projects, here are some common reasons of using the namespaces in these projects...

Quick Q: Are std::threads run in the order they're created?--StackOverflow

Quick A: There is no guarantee that threads will run in a given order.

Recently on SO:

Why don't these threads run in order?

When I run this code:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex m;

int main()
{
    std::vector<std::thread> workers;
    for (int i = 0; i < 10; ++i)
    {
        workers.emplace_back([i]
        {
            std::lock_guard<std::mutex> lock(m);
            std::cout << "Hi from thread " << i << std::endl;
        });
    }

    std::for_each(workers.begin(), workers.end(), [] (std::thread& t)
    { t.join(); });
}

I get the output:

Hi from thread 7
Hi from thread 1
Hi from thread 4
Hi from thread 6
Hi from thread 0
Hi from thread 5
Hi from thread 2
Hi from thread 3
Hi from thread 9
Hi from thread 8

Even though I used a mutex to keep only one thread access at a time. Why isn't the output in order?

C++ STL for Embedded Developers--John Hinke

E.S.R. Labs presents its STL library adapted to embedded environments and discusses some of the choices they made for it:

C++ STL for Embedded Developers

by John Hinke

From the article:

C++ embedded programming is very difficult. There are some limitations that are not always present in traditional programming environments such as limited memory, slower processors, and older C++ compilers.

We have developed a set of best-practice processes and frameworks to support writing high-quality embedded applications...

A gotcha with Boost.Optional --Andrzej Krzemieński

Have you used the Boost.Optional library? There is one thing you might need to keep an eye on as explained by Andrzej.

  A gotcha with Optional

  by Andrzej Krzemieński

From the article:

This post is about one gotcha in Boost.Optional library. When starting to use it, you might get the impression that when you try to put optional<T> where T is expected, you will get a compile-time error. In most of the cases it is exactly so, but sometimes you may get really surprised...

Quick Q: Is an acquire_release fence enough for Dekker synchronization?--StackOverflow

Quick A: No, because acq_rel doesn't prevent reordering a store to x followed by a load from y... seq_cst does.

Recently on SO:

Why isn't a C++11 acquire_release fence enough for Dekker synchronization?

The failure of Dekker-style synchronization is typically explained with reordering of instructions. I.e., if we write

atomic_int X;
atomic_int Y;
int r1, r2;
static void t1() {
    X.store(1, std::memory_order_relaxed)
    r1 = Y.load(std::memory_order_relaxed);
}
static void t2() {
    Y.store(1, std::memory_order_relaxed)
    r2 = X.load(std::memory_order_relaxed);
}

Then the loads can be reordered with the stores, leading to r1==r2==0.

I was expecting an acquire_release fence to prevent this kind of reordering:

static void t1() {
    X.store(1, std::memory_order_relaxed);
    atomic_thread_fence(std::memory_order_acq_rel);
    r1 = Y.load(std::memory_order_relaxed);
}
static void t2() {
    Y.store(1, std::memory_order_relaxed);
    atomic_thread_fence(std::memory_order_acq_rel);
    r2 = X.load(std::memory_order_relaxed);
}

The load cannot be moved above the fence and the store cannot be moved below the fence, and so the bad result should be prevented.

However, experiments show r1==r2==0 can still occur. Is there a reordering-based explanation for this? Where's the flaw in my reasoning?

C++ Has Become More Pythonic -- Jeff Preshing

A nice article pointing out similarities between modern C++ and Python:

C++ Has Become More Pythonic

by Jeff Preshing

From the article:

C++ has changed a lot in recent years. The last two revisions, C++11 and C++14, introduce so many new features that, in the words of Bjarne Stroustrup, “It feels like a new language.”

It’s true. Modern C++ lends itself to a whole new style of programming – and you can’t help but feel Python’s influence on this new style. Ranged-based for loops, type deduction, vector and map initializers, lambda expressions. The more you explore modern C++, the more you find Python’s fingerprints all over it.

Was Python a direct influence on modern C++? Or did Python simply adopt a few common idioms before C++ got around to it? You be the judge...

Quick Q: How do I add elements to a 2D vector of ints?--StackOverflow

Quick A: Index into the desired sub-vector and call push_back.

Recently on SO:

Inserting elements into 2D vector

So I'm creating a class that implements an adjacency list. Currently in my class definition I initialized two vectors:

vector<vector<int>> adjList;
vector<int> neighbors;

and I declared two functions that I plan to use to make it:

bool constructAdjList();
bool insertIntoAdjList(int, int);

It's getting difficult wrapping my head around 2D vectors. I understand that it is essentially a vector of vectors, but I'm confused about how to insert a new value into one of the "subvectors". For example, I am able to create an adjacency list in createAdjList that is empty with the following loop:

for (int i = 0; i < numOfValues; i++){
    neighbors.push_back(0);
    adjList.push_back(neighbors);
    neighbors.clear();
}

But how can I say, push_back the value 5 to the 4th vector in adjList, which would be represented in my insertIntoAdjList function as

insertIntoAdjList(4, 5);

I know I can access a specific value in a 2D vector by saying adjList[4][1], but how can I push one onto it?

Thanks!

A quick poll about order of evaluation -- Herb Sutter

A quick Monday poll:

A quick poll about order of evaluation...

by Herb Sutter

From the article:

Consider this program fragment:

std::vector<int> v = { 0, 0 };
int i = 0;
v[i++] = i++;
std::cout << v[0] << v[1] << endl;

My question is not what it might print under today’s C++ rules. The third line runs afoul of two different categories of undefined and unspecified behavior.

Rather, my question is what you would like the result to be. Please let me know... [click for poll]