Author: Eric Elfving

IT-konsult på Alten med bakgrund som universitetslärare.

Static code analysis and clang-tidy

The April meeting was all about static analysis with a focus on clang-tidy. We spent some time writing our own checker for clang-tidy to catch cases which would have been seen using the compiler flag -Woverloaded-virtual, i.e. redefining a virtual function in a derived class that doesn’t override a virtual function in a base class with the same name.

As Filip pointed out, the solution didn’t really work for cases where we have several base classes so I rewrote the solution a bit.

Here is the fixed solution:

And of course an updated test suite

Using the compiler to find bugs

During session 2, I discussed a couple of techniques to use the static type system to let the compiler find my bugs. Here is a “short” summary of the code we created during the session.

For our first problem, assume that you are creating a small library for terminal 2D-graphics (because that’s a very novel idea…). You create a function with the following signature to let the user print a character at a specific coordinate:

As long as the user calls this function with coordinates in the x,y-plane, this will work fine, but what if the user doesn’t read our (of course excellent) documentation and instead tries to call it with a row and column? The compiler would even allow for this stupid mix-up:

The first step of helping the user (and ourselves) is to add an extra level of abstraction!

This extra type makes it difficult for the user to call our function with it’s parameters reordered. The user also get the extra bonus of having our Point type to use locally.

Of course, the user can still use it in stupid ways:

We could of course have made Point into some advanced class with private data members, but it doesn’t really make sense here; Point doesn’t have any invariants to keep track of! We could make it easier to use though. Lets start by adding a couple of reference members so that I can access y as row and x as column:

We can still initialize a point with values for only x and y and the compiler will initialize the references according to our default values. It is, however, not possible to only initialize a Point by only providing row and column 🙁

What I want to do now is to make the following construct valid:

Now, this doesn’t really look like C++, but it is possible to implement. Assume that there are variables named row and column available in this scope and that we can assign integers to those variables, then this would work. The question is what type should those variables have? The simplest solution would be to make them int. This would however not work since we already have a constructor that accepts two int parameters – the one that initializes x and y. Let’s instead create new types that fulfills the requirement above.

Now we create our variables and add a constructor to Point:

We could of course hide the value member of Row_Type by adding a conversion operator:

If we make the same change to Column_Type, we can change our Point constructor accordingly:

The next problem I wanted to “fix” was to create a wrapper for integral types that makes sure that we won’t go outside a pre-defined range of the type. Our goal at the beginning was to have a type that supported addition with positive integers and will throw an exception iff the addition makes the value go out of range.

To test our code we use the excellent catch library. When we are done, we want this test case to pass

Lets start with the basics, a template class that can be constructed from a number of underlying type and can be converted back to the underlying type implicitly.

Now it’s time to add addition. I usually like to implement it by first implementing compound addition. In this example, we’ll just support addition with a positive integer, for a full implementation we’ll have to take care of addition with negative values as well…

So, great, we now have a type that represent an enumerable type that makes sure the internal value is in the given range. Now lets make it a bit more usable and make it possible to change the addition behavior. Instead of throwing, we might want to clamp the value. To fix this, we’ll move the addition behavior to a policy class. This policy has to be a template class (or possibly have a templated function that does the addition).

Now we can add a new policy for clamping:

With this modification, the following test case should pass.

To help the user, default values for template arguments could be nice.

We could even add templated aliases.

Now we have a type that allows the user to have a safe type for integral values. It’s rather simple to modify the behavior by adding a new policy and best of all, it’s still really effective. Check out the full example on godbolt!

Meetup skapad

För att synas mer och få en gemensam plats för anmälan och diskussion om event har jag nu skapat en plats på meetup. Januarimötet är nu upplagt för anmälan!

LinkCpp – Linköpings C++ User Group

Linköping, SE
1 Members

Detta är en plats där Linköpings C++-intresserade kan mötas och prata C++. Vi ses en kväll per månad (normalt sett den andra onsdagen varje månad), lyssnar på intressanta pres…

Next Meetup

LinkCpp – möte 2

Wednesday, Jan 9, 2019, 5:00 PM
1 Attending

Check out this Meetup Group →

LinkCpp på Meetup

Sammanfattning Möte 1

Det första mötet har äntligen varit och här kommer mina tankar om det mötet.

  1. Väldigt roligt med över 20 deltagare
  2. Bra start med lite mat för att lära känna varandra under enklare  former (tack Alten!)
  3. Vi bestämde oss för att ses igen onsdagen den 9/1 och därefter den andra onsdagen varje månad. Lokal och tid får undersökas vidare.
  4. Roligt med många frågor och sidodiskussioner, både med mig som talare men även mellan deltagarna – precis därför vi (eller åtminstonde jag) är där!
  5. Vi ska försöka ha en lista där man får anmäla ämnen man gärna lär sig mer om för att göra det lättare att hitta något att prata om på mötena. Tills jag hittar en spam-fri lösning här kommer jag skicka ut en länk till ett google-doc till tidigare deltagare. Kontaka mig om du också vill ha tillgång till detta dokument.
  6. Förslag till sidoprojekt (utöver vanliga presentationer) tas även det emot i ovannämnda dokument. Några förslag vi diskuterat är workshops och gemensamma programmeringsprojekt.

Nedan finns möjlighet att ladda ner de slides jag presenterade under mötet. Bilderna ägs av respektive skapare, i övrigt får ni använda materialet som ni vill.


LinkCpp är en lokal user group för C++ baserad i Linköping. Klicka på länkarna uppe till höger för mer information och anmälan till våra träffar!