Category Archives: 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.

1 Comment

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

ACCU Meetup: Code Craft

Jason Gorman of CodeManShip gave an interesting talk on code craft this week. The talk began with the business case for Code Craft, based on the cost of changing a line of code. If you compare the number of changes in source code repository to the expense of their development teams, the cost generally increases massively over time – 40X more expensive per line of code change after 8 years for one company. The same hockey-stick chart appears in Kent Beck’s book “Extreme Programming Explained”. Code Craft skills tend to flatten the cost-of-change curve, which is good for the business, and make the code easier to change, which is good for the developers.

Code Craft Skills

Write good unit tests, use version control, do continuous integration, apply design principles, refactor code safely.

Cost – if the cost of a change in design is 1, then the cost in implementation is 6.5, in testing is 15 and in maintenance is 100.  Bringing testing forward in the development process gives a massive return on investment.  Legacy code can be defined as any code that doesn’t have fast running, automated unit tests that can discover a bug quickly – enabling a cheap fix.  You must automate testing and enable the feedback loop to iterate quickly – ideally in minutes or seconds.

Readability – 50%-80% of time spent on a codebase is reading code, not writing it.  Making code easier to read and understand has a great pay-off.  Code that’s hard to understand is easy to break.

Complexity – attack complexity, try to replace it with the simplest thing, which is less likely to be wrong.

Duplication – never copy/paste code, especially off the internet!  You have no idea if it works or even compiles.  Making changes to common logic is multiplied if there’s duplicate code.  Duplication is the opposite of reuse – generate an abstraction to help improve the design.  Duplication can be hard to spot (e.g. customer playing several roles which could have been parameterised).

Ripple Effect – a change to one area of code breaks a much wider circle of code.  Cost of change greatly increased – need to have a local effect from a small change to code.

Principles of Clean Code

The speaker also coaches teams in the following principles:

1. Shorter feedback loops – automated unit testing.  Not possible with manual testing iterations or a manual testing phase.  Automated system testing can give good coverage, but is often too slow, can take hours to run.  Need to run in minutes or seconds.  Ideal chain is Unit Testing -> Integration testing -> System testing.  Want most of the testing in first layer, minimal number of smoke tests in the top System layer.

2. Simple Design – the code works, clearly reveals intent, free of duplication, made out of simple parts.  Need another pair of eyes to check the code is easy to read.  Code review your own code every few minutes.

3. Single responsibility – traditionally, this is taught as classes should only have one reason to change.  Or better, look at the number of combinations of the sections of code implemented in a function – it’s more powerful to break functions into smaller parts then use composition to implement the larger function.  Smaller components/functions => many more ways to re-use. So give each piece of software a single responsibility.

4. Tell, don’t ask – lots of low-level coupling between objects. Better to have objects sharing smallest possible interface to each other. Don’t pass the whole object – pass the data needed to do the operation.  Put the work where the knowledge lives – do the work in the right place so that data and behaviour belong together.

5. Dependency Inversion – you should be able to swap your dependencies.  Talk to dependencies as abstractions through interfaces.  Eg1 all commands inherit from ICommand and high-level components work on generic interface, not concrete classes.  Eg2 VideoRental example, rather than coupling to Imdb, replace with an interface.  Better for mocking/testing as well.

Leave a comment

Filed under Meetup, Programming

How to report performance improvements

Bruce Dawson blogged about typical language when reporting speed-ups. Interesting that he found confusing/plain wrong examples in the real world as well as in software development. 

I usually try to communicate improvements in the style “10X faster” as well, to avoid any ambiguity. 

Leave a comment

Filed under 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