Category Archives: C++

Modern C++ in Embedded Systems

I was thinking about C++ for embedded environments recently and wondered how much of today’s Modern C++ was recommended for use. I found an excellent article by Dominic Herity on the subject:

  1. Modern C++ in Embedded Systems – part 1
  2. Modern C++ in Embedded Systems – part 2

Even better, Dominic linked to some presentation materials Scott has published electronically on the subject. I’ve long been a fan of Scott’s writing and wasn’t aware of this electronic book, so I’m reading that next.

Leave a comment

Filed under C++, Programming, Tech Book

C++ London Meetup: Type Punning and Counting Nanoseconds

September’s C++ London Meetup featured two talks: Type Punning by Timur Doumler and Counting Nanoseconds by David Gross of Optiver. Optiver were the generous sponsors of this event, hosted at SkillsMatter near Moorgate.

Counting Nanoseconds

Optiver are based in Amsterdam and operate in the High-Frequency Trading sphere. Naturally, they need code to be fast in order to take trades more quickly than their competitors, but the benefits of fast code also extend to minimising energy costs in data centres and extending battery life on portable devices for other applications. David Gross spoke about micro-benchmarking – boiling code down to very small numbers of instructions to aid comparisons and improve performance. The caveat was that it’s always vital to measure performance in production using real data as well as doing this offline, low-level analysis against potted test cases. David warning against relying on the high-resolution clock which can be problematic (may not be steady and may not have the resolution you need). He often uses Intel Time Stamp Counter (TSC), although that’s not the original intention of that metric.

Type Punning

Timur is fascinated by the ability to take an object and treat it as another type in C++. Yet, in many cases, this results in undefined behaviour. For example:

class Gizmo {
  public:
  virtual void print(){ std::cout << "Gizmo\n"; }
};
class Widget {
  public:
  virtual void print(){ std::cout << "Widget\n"; }
};
Gizmo g;
Widget* w = (Widget*)(&g);
w->print();

The behaviour of this code is undefined, because Widget and Gizmo are unrelated, although both have a virtual print function, so the virtual function table is the same. The standard says that you can’t call a method on a reinterpret-cast’d object – you can only cast it back to the actual type of the object. But on most compilers tried by Timur, the code runs and prints “Gizmo”. He referenced the CppCon 2018 talk, Undefined Behaviour is Not an Error.

Other examples concerned how to share memory across multiple data types, such as treating 4 bytes as either a char array or as a float. Even using a union can result in undefined behaviour, because only one member is ‘alive’ at a time. In order to write portable code, you must consider aliasing rules, object lifetime rules and alignment rules. In same cases, you can use C++17’s std::memcpy to ensure alignment (but only if the types are the same size and trivially copyable). std::bit_cast is coming with C++20. And in C++23, there’s a proposal for std::start_lifetime_as(char[]) to implicitly create objects, for example when reading from a buffer.

The video for this talk is available on SkillsCast.

Leave a comment

Filed under C++, C++ Code, Meetup, Programming

C++ London Meetup: C++ 11 was only the Beginning

I was lucky to get a place at this month’s C++ London meet up, having a limited number of seats and being hosted by Smarkets at their offices in St Katherine’s Dock. Smarkets are an online betting exchange – and they’re currently hiring!

This evening was started by Alex Schmolck, presenting his work configuring the development and build systems for Smarkets. He’s experimented with Vagrant and Docker, but is now an advocate of Nix. He admits that Docker is initially more productive, but Nix has the edge for its efficiency and speed.

The main talk (see slides) was given by Mateusz Pusz, showing a series of examples to demonstrating how a body of code can evolve and improve significantly with the features introduced by C++11, C++14, C++17 and soon C++20.

For example, implementing functions with variable numbers of parameters – such as for populating a container of items for a testing library. With C++98, this might have led to many overloads with increasing numbers of arguments (but only ever handling up to some hand-coded limit). With C++11 onwards, you could use variadic templates, handling any number of parameters. And with C++17 onwards, you could use fold expressions to simplify the code further (no need to the ‘base class’ template overload).

Another interesting example was the evolution of Compile-Time Dispatch. Whereas even C++ 11requires hand-rolling overloads on a hierarchy of tag classes, post C++17, you can use constexpr to organise the code within a single method.

Leave a comment

Filed under C++, Meetup, Programming

C++ London Meetup: Pointers and Errors

This C++ Meetup, held at Skillsmatter, was split into two talks.

The first by Ervin Bosenbacher was Modern C++ Smart Pointers in C++ 17, 20 & Beyond. It served as a good introduction to smart pointers and motivation for using them, particularly for developers new to C++ (or those who had not yet started to use C++11). The talk covered:

  • Issues with use of raw pointers (ownership, how to delete, exception safety)
  • std::auto_ptr and why not to use it
  • std::unique_ptr and std::shared_ptr – trade-offs and performance figures
  • Use RAII – assign a raw pointer to a smart pointer as soon as it is allocated

A good point was that use of std::shared_ptr means that other parts of the codebase can modify an object that you’re sharing – so synchronisation primitives (such as a std::mutex) are needed to ensure access to the underlying resource is thread-safe. This is often overlooked because the reference counting *is* thread-safe. In C++20, we will get atomic smart pointers to help with this.

Discussing std::shared_ptr with a friend, I also learnt about a secret constructor on std::shared_ptr to share the resource control block and keep a parent pointer alive.

The second talk was Arno Schödl on Error Handling. He described how Think Cell grade errors into different levels, each with a clearly defined error handling strategy. The aim is to minimise coding and testing overhead whilst maximising the ability to capture and debug error conditions.

Leave a comment

Filed under C++, Meetup, Programming

C++ London Meetup: Tuppence more on Standard Algorithms

This evening of talks was split into a set of Lightning Talks in the first half followed by a discussion about the Standard Library in the second half.

Part 1 – Lightning Talks
Richard Chandler – ACCU 2018 Trip Report – much on C++14 and C++17 standards to catch up on as well as introduction to Kotlin and a number of talks on diversity and inclusivity.

Phil Nash – East End Story
Phil dived into the controversial East Const v West Const debate

    void f( T const& t ) // East const
    void f( const T& )   // West const

i.e. should you put the const before or after the type. This topic was introduced by Dan Saks in 2011 – Simplifying const Syntax, Dr Dobbs and revived by Jon Kalb in A Foolish Inconsistency.

“Const applies to what is on its left, unless there is nothing to the left, in which case it applies to what is on the right.” But using east const format, it always applies to the left! West const reads more naturally from left to right, e.g. “const integer” – the East const argument is that you would always read declarations inside out and right to left!

    char const * const pc = str // pc is a const pointer to a const char, reading right to left

Developers are already accustomed to using East const for const member functions (must put const on the ‘east’ side). And there are other examples of going East:

    // moving the return type further east as a result of c++11
    auto someFunc( int i ) -> std::string; 

    // you have to put the return type on the east side
    auto lambda = [] -> double { return 0; } 

Other considerations: Swift/Haskell have trailing return type; putting auto at the start of list of function definitions, the start of the names line up; C++ standard NL.26 says use conventional const notation, endorses West Const notation, but is itself inconsistent!

Phil is now using trailing return types everywhere in production code – see his blog, East End Functions (LevelOfIndirection.com)

Stewart Becker – A Fool’s Consistency, the rebuttal (Jonathan Muller’s talk)

East const gives more consistency? If 83% of people write const T (i.e. West const), you need to be consistent with everyone else in your codebase.
Const pointer to const fallacy – with modern c++, use const std::string_view instead. Can use std::as_const(x) to get the const cast.
Right-to-left fallacy – but we read loops etc from left to right, and ‘const’ is an adjective which goes before the noun in English.
Clockwise-Spiral rule for function pointers.

const east west const – you are allowed to write const in both the East and West positions!!

Part 2 – Tuppence More on Standard Algorithms – Iakov Sergeev
Iakov believes the standard algorithms should make code easier to implement and read, but are forgotten in practice. He raised issues with inconsistencies and the learning curve to use STL (output iterator, predicates, modifying input sequences, could take both begin/end iterators).

Historically, the predicates were hard to implement where you had to supply a functor to call algorithms. Now, with lambdas, it’s much easier and localised to call algorithms.

The audience felt that Eric Niebler’s work on the Ranges TS should help a lot with adoption of standard algorithms.

Leave a comment

Filed under C++, Meetup, Programming

C++17: Lambdas

C++ has supported lambda functions since C++11, and post-C++14 even supported generic lambdas. C++17 adds a quirky feature to enable ‘copy capture’ of ‘this’. Here’s an example of it in action:

struct MyStruct
{
    auto lambda_with_this() // Before C++17, copies this pointer
    {
        auto f = [this]{ return value; };
        return f;
    }
    
    auto lambda_with_star_this() // C++17 - takes a local copy of *this
    {
        auto f = [*this]{ return value; };
        return f;
    }
    
    int value;
};

TEST( Cpp17, lambda_capture_this )
{
    MyStruct s{ 42 };
    auto f = s.lambda_with_this();
    s.value = 101;
    EXPECT_EQ( 101, f() );
}

TEST( Cpp17, lambda_capture_star_this )
{
    MyStruct s{ 42 };
    auto f = s.lambda_with_star_this();
    s.value = 101;
    EXPECT_EQ( 42, f() );
}

Notice that in the second case, we capture a copy of our object – so the lambda returns the value held at the point of capture (42) rather than the value when it is called (101). This can be very important if ‘this’ has been destroyed between the creation of the lambda and the time at which it’s called.

Now, C++14 also supported generalised lambda capture, which meant you could (re-)name variables when capturing (and provided a neat way to capture-by-move):

    auto f = [tmp = *this]{ return tmp.value; };

But the C++17 code is more concise. See this useful StackOverflow post for more discussion.

Another advance in C++17 is that lambdas are implicitly constexpr – so you can now use them in compile-time contexts, like declaration of std::array:

// lambda explicitly constexpr since C++17
auto square = []( auto v ){ return v*v; }; 

TEST( Cpp17, lambda_implicitly_constexpr )
{
    // std::array calls 'square()' at compile time
    std::array<int, square(4)> values; 
    EXPECT_EQ( 16, values.size() );
}

See also the previous C++17 post.

Leave a comment

Filed under C++, C++ Code, Programming

C++17: Nested Namespaces

Another crowd-pleaser in C++17 is the ability to declared nested namespaces without literally nesting them. In the past, you had to do this, which involves a lot of wasted whitespace:

namespace NestedNamespaces
{
    namespace Really
    {
        namespace Work
        {
            auto return_int(){ return 42; };
        }
    }
}

Happily, you can now do this instead:

namespace NestedNamespaces::Really::Work
{
    auto return_int(){ return 42; };
}

TEST( Cpp17, nested_namespaces )
{
    EXPECT_EQ( 42, NestedNamespaces::Really::Work::return_int() );
}

See also previous C++17 post.

2 Comments

Filed under C++, C++ Code, Programming

C++17: Structured Bindings

This is one of a series of posts on C++17 features – see also previous post on if initialisers.

Structured bindings are a convenient way of handling multiple return values from functions. Whilst F# has been able to do this:

let f() = 42, "Hello, World" // return a pair of values
let a, b = f() // assign a and b to the values returned by f

in C++, we’ve had to declare the variables up front and use std::tie to assign values (so not only does this take more lines, we also have to default initialise the variables then throw away the defaults).

auto t = std::make_tuple( 42, "Hello, World" );
int a, b;
std::tie( a, b ) = t;

The new structured bindings are much more concise, even if the use of square brackets came as a surprise. Even better, you can use structured bindings with structs and std::array.

int my_int{ 42 };
std::string my_string{ "Hello, World" };
bool my_bool{ true };

auto return_pair()
{
    return std::make_pair( my_int, my_string );
}

auto return_tuple()
{
    return std::make_tuple( my_int, my_string, my_bool );
}

struct MyStruct
{
    int a;
    double b;
    int c;
    
    static MyStruct Expected;
};

MyStruct MyStruct::Expected = { 1, 2.2, 3 };

auto return_struct()
{
    return MyStruct::Expected;
}

auto return_array()
{
    return std::array<int,3>{ 1, 2, 3 };
}

auto return_map()
{
    return std::map<int, std::string>{ {1, "a"}, {2, "b"}, {3, "c"} };
}

TEST( Cpp17, structured_bindings_for_pair )
{
    auto [i, s] = return_pair();
    
    EXPECT_EQ( my_int, i );
    EXPECT_EQ( my_string, s );
}

TEST( Cpp17, structured_bindings_for_tuple )
{
    auto [i, s, b] = return_tuple();
    
    EXPECT_EQ( my_int, i );
    EXPECT_EQ( my_string, s );
    EXPECT_EQ( my_bool, b );
}

TEST( Cpp17, structured_bindings_for_struct )
{
    auto [i1, d, i2] = return_struct();
    
    EXPECT_EQ( MyStruct::Expected.a, i1 );
    EXPECT_EQ( MyStruct::Expected.b, d );
    EXPECT_EQ( MyStruct::Expected.c, i2 );
}

TEST( Cpp17, structured_bindings_for_array )
{
    auto [i1, i2, i3] = return_array();
    
    EXPECT_EQ( 1, i1 );
    EXPECT_EQ( 2, i2 );
    EXPECT_EQ( 3, i3 );
}

TEST( Cpp17, structured_bindings_for_iterating_over_map )
{
    for ( const auto& [key,value] : return_map() )
    {
        switch (key)
        {
            case 1: EXPECT_EQ( "a", value ); break;
            case 2: EXPECT_EQ( "b", value ); break;
            case 3: EXPECT_EQ( "c", value ); break;
            default: break;            
        };
    }
}

For me, the best examples come when combining features – the range-based for loop with structured bindings is a thing of beauty.

See also next C++17 post.

2 Comments

Filed under C++, C++ Code, Programming

C++17: if initialiser

I attended a C++17 presentation by Nicolai Josuttis last year, but at the time, my laptop’s compiler didn’t support any of the features to try them out. After a recent update, it turns out that many are now supported, so I’ve written a few unit tests using GTest.

The first feature I tried was the if initialiser. This feature looks a bit odd at first, because C++ programmers are so conditioned to seeing if statements containing a single condition. Allowing an initialiser statement as well

if ( initialiser; condition )

means that you can initialise a variable and test it on the same line. It also prevents the variable being used outside the scope of the if statement – this prevents accidental re-use if you subsequently mis-type a variable name.

auto return_int()
{
   return 101;
}

TEST( Cpp17, if_initialiser )
{
    // NB we can use i in the body of the if or the else
    // Also, must have a variable name for the object to live in the whole statement
    // (so must name locks taken, even if not used in the body, otherwise it's a temporary).
    if ( auto i = return_int(); i < 100 )
    {
        EXPECT_TRUE( i < 100 );
    }
    else
    {
        EXPECT_TRUE( i >= 100 );
    }
}

TEST( Cpp17, if_initialiser_with_map_insert)
{
    std::map<int, std::string> my_map{ {42, "Hi" } };
    
    if ( auto[it, inserted] = my_map.insert( std::make_pair(42, "Bye" ) ); !inserted )
    {
        // See also StructuredBindings for iterating over a map
        auto& [key,value] = *it; // iterator is pair of key and value
        EXPECT_EQ( 42, key );
        EXPECT_EQ( "Hi", value );
        
        value = "Bye"; // update the value
        EXPECT_EQ( "Bye", my_map[42] );
        
        // key = 43; // compile error! - cannot assign to const key-type
    }
}

See also next post on C++17 Structured Bindings.

1 Comment

Filed under C++, C++ Code, Programming

C++ London Meetup: Distributed C++

This is the first time that the Stockholm C++ and the London C++ group have combined to produce a series of lightning talks, half given from Sweden and half from England.

Bjorn Fahller: A variant of recursive descent parser
Raised issues with generators and lexers when trying to do this, particularly for debugging. What about std::variant? Has knowledge of the type that it’s holding, and there’s std::visit that can overload function call operators for each type.

// visitor class is defined elsewhere, too far from its declaration!
visitor visitor_obj; 
int i = std::visit(visitor_obj, variant_var );

// Alternative - Bjarne's overload approach with lambdas  
auto t = lexer.next_token();
std::visit(
      overload{
    [=](ident var){ return lookup( var.value); },
    [=](number n){ return n.value;}
  }
  , t );

The template overload makes clever use of deriving from a lambda via templates and C++17 features. The details are here.

Bjarne also referenced: Matt Kline’s post on std::visit is everything wrong with modern c++.

Mikael Rosbacke – Yet another state machine tool
How to make it easy to write state machines? Hierarchy, entry/exit action, queuing, no heap allocations, no code generation.

Mikael’s framework provides a finite state machine base class from which you derive and post events as they arrive. Each state derives from a framework state base class, and provides an event method to transition into other states.

See https://www.github.com/rosbacke/mcu-tools.

Simon Pettersson – The Art of manufacturing types
Compile time lookup-table – with a very convincing demo in compiler explorer, where marking the lookup result as constexpr changed the compiled code to simply a constant.

See https://github.com/simonvpe/cmap

Paul Dreik – what is this std::forward thing?
A beginner’s guide to forwarding references – suppose you want to write a wrapper function that does some action then calls an underlying function. You would need to use std::forward like this, otherwise the wrong overload of function f would be called:

struct S{};

void f(S& s){ puts("f(S&)"); }
void f(S&& s){ puts("f(S&&)"); }

template<typename T>
void wrap(T&& t){
  f(std::forward<T>(t));
}

int main(){
  S s;

  wrap( s );
  wrap( S() );
}

Dominic Jones – Reflecting on names – Facilitating expression tree transforms
Would like to transform expressions differently according to the variable inputs:

transform(a + a) -> 2 * a
transform(a + b) -> a * b

Thoughts are to introduce varid, a keyword based on the position of the declaration of the variables. Evaluated at compile time, a bit like address-of, possibly the hash of the file name, row and column of the referenced variable. The use is for faster automatic differentiation.

Phil Nash – a Composable Command Line Parser
When writing Catch 1.0, Phil wrote Clara 0.x – a command line parser library (but it never reached maturity). As part of Catch 2.0, he has written and completed Clara 1.0! The latest version of the library introduces class Opt which declares command line options, which are then combined with the pipe operator.

auto a = 
      Opt( width, "width" )
        ["-w"]["--width"]
        ("How wide should it be?")
    + Opt( name, "name" )
        ["-n"]["--name"]
        ("By what name should I be known");

See github.com/philsquared.

C++ London University
Tristan is a volunteer at this initiative to support interested parties in learning C++. Hosted by Mirriad, it comprises a mixture of lectures, exercises and covers the basics. 4 meetings so far, looking for tutors and more students! Tristan Brindle – tcbrindle@gmail.com, http://www.cpplondonuni.com, gitHub.com/cpplondonuni

Ian Sheret – Automatic Differentiation in C++
For mathematical functions in various domains. z = f(x,y) e.g. hypotenuse as root of sum of squares in a triangle. But what about values of z near x and y, if we change by some epsilon? Can use Ceres Jets to keep track of the differentiated values. Templatise the function so that you can pass in the Jet variables (instead of simply doubles). Then the return value automatically returns the derivatives as well as the function value!

Andrew Gresyk – Effective Screening Interviews
Consider cultural fit and technical fit – but if they do a separate cultural interview, 80% of people pass that anyway. Need to test communication and ability to write real code – asking knowledge questions only is not sufficient. Replace questions with practical exercises.

Jamie Taylor – Beyond SSO: The Merits of Fixed-Length Strings
std::string – easier and safer to work with than a c string. Handles memory allocation. Uses short string optimisation – short strings go on the stack, so no dynamic allocation.

But – length of SSO buffer is implementation defined. If string is too long, will dynamically allocate. Also, the fixed buffer inside the std::string will frequently be much larger than a very small string you wish to create (typically 32-bytes).

// fl::string is an alternative where the size of the buffer
// is customisable in the template parameters
template<size_t length>
class fl::string
{
  // Implementation elided!
  char m_data[length];
};

Don’t want to pay full cost of e.g. 32 byte std::string if your string will only be 3 characters. This allows you to specify the maximum length in the template. Get average 6x and 13x speed-ups for 8 and 32 character strings for both creation and access of string keys in maps. Can be more friendly for your cache and great for low-latency.

Vittorio Romeo – you must type it out 3 times
Vittorio wants to write a generic log and call method with a noexcept handler – but has to type the same forwarding signature three times! Solution could be the “=>” operator that’s been proposed.

Leave a comment

Filed under C++, Meetup, Programming