Logo

Blog


Early bird for "C++1x für eingebettete Systeme kompakt" ending soon

If you are interested in a one day technical seminar about C++ for embedded systems you might consider mine: C++1x für eingebettete Systeme kompakt. The early bird is ending at 25th of September.

You'll find links to the details for all my public appearances at my talks and training page or for this particular one also at my partner's site. I look forward to see you there.

Andreas

Use of the comma operator

Last week, I read a blog article from Jonathan Boccara called "Getting Along With The Comma Operator in C++". At the end of the article I felt bad for the comma operator. Jonathan pointed out an example where the comma operator gets in our way. The article is great. However, to me it looks like the comma operator is not needed and can just be in our way. In this post I will point out two use-cases where the comma operator is in fact helpful.

Let's start with C++11. Do you remember how great it was to get that language update? Especially after all the years seeing other languages arise and or improve? There are many things which got introduced or improved with C++11, one I like is constexpr. I like to focus on constexpr-functions here. They got improved a lot with C++14 and again with C++17. Unfortunately, not all of us are lucky enough to get to use the latest standard.

Back in C++11 they are, let's say restricted. Such functions can more or less contain only a single return statement. This restriction makes it hard to write constexpr functions in C++11. One particular hard area is an assertion. Assume there is a constexpr function:

1
constexpr size_type CheckLength(size_type len)

The length parameter len must be in a certain range. Otherwise, we will get a buffer over- or underflow. How can this be achieved? The comma operator is our friend:

1
2
3
4
constexpr size_type CheckLength(size_type len)
{
    return ((len <= MAX_SIZE) ? (void)0 : assert(false); ), len;
}

Thanks to the comma operator we still have only a single return statement. The comma operator helps us, to separate the assert-expression from the actual return value: len. The idea is, that this function always returns len. Except if the assert condition is not met, then is fires the assert and the program terminates. Still len is the only return value. Here the same, but in a bit more readable and reusable fashion:

1
2
3
4
constexpr size_type CheckLength(size_type len)
{
    return ASSERT(len <= MAX_SIZE), len;
}

Either the ASSERT will kick in or this functions returns len. The ASSERT-macro itself is a bit more complicated. You can find a working version in abseil marco.h. Which is used, for example in string_view.h.

Another C++11 and later feature which can be used with the comma operator are variadic templates. To be more precise the pack expansion:

1
2
3
4
5
template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args)
{
    (v.push_back(args), ...);
}

This is part of an example from cppreference.com. Here the comma operator is used to expand the pack and execute an operation for each pack-member. In this case push_back. Jason Turner once wrote an article exploring even more (ab)uses of variadic templates and the comma operator: Folds (ish) In C++11.

As you can see, as much the comma operator can be annoying, but also helpful.



I hope you learned something with this article.

Andreas

NDC { Oslo } 2018 slides and video available

I'm pleased to announce that the video C++: Be type-safe - The journey of determining the number of elements in an array of my presentation at NDC { Oslo } in June is available youtube:



As last year, aside from youtube the conference organizers decided to upload it to vimeo as well. It's up to you to decide on which platform you enjoy watching it most.

You can find the slides of this talk at my talks and training page a couple of days ago. This site also contains details for my other public appearances.

I hope you enjoy the material. Happy viewing!

Andreas

Public appearances 2018

I will again work together with QA Systems for a one day technical seminar C++1x für eingebettete Systeme kompakt.  The seminar will be held in Stuttgart November 6. Early bird is available until September 25.

There are also at least two upcoming talks. The first one is at ADC++ in May in Munich. Together with C++ experts like Nicolai Joscuttis,  Steve Caroll and Michael Wong I talk about type-safety with templates.

I'm also proud to be in Oslo again, speaking at NDC { Oslo }. Talking about Be type-safe - The journey of determining the number of elements in an array .

As usual, you’ll find links to the details for all my public appearances at my talks and training page or for this particular one also at my partner’s site.

I'm looking forward seeing you at some of these events.

 

Andreas

 

Safer type casting with C++17

I like to write less code and letting the compiler fill in the open parts. After all the compiler knows most and best about these things. In C++ we have a strong type system. Valid conversions between types are either done implicitly or with cast-operators. To honor this system we express some of these conversions with casts like static_cast:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
void Before()
{
  Foo foo{1.0f};

  auto floatFoo = static_cast<float>(foo);

  printf("%f\n", floatFoo);

  Bar bar{2};

  auto intBar = static_cast<int>(bar);

  printf("%d\n", intBar);
}

Here is a potential class design for the types Foo and Bar:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Foo
{
public:
  Foo(float x)
  : mX{x}
  {}

  operator float() const { return mX; }
  operator int() const { return static_cast<int>(mX); }

private:
  float mX;
};

class Bar
{
public:
  Bar(int x)
  : mX{x}
  {}

  operator int() const { return mX; }

private:
  int mX;
};

Imaging that you have dozens of such casts all over your code. They are fine, but a constant source for errors. Especially Foo is problematic. It can convert to a float as well as to an int.

What I like to achieve, is that I can call one function, let's name it default_cast, which does the cast for me. All the casts which are in 90% of the code the same.

Depending on the input type it converts it to the desired default output type. The resulting code size and speed should match the code I could write by hand. Further it all of it must happen at compile time, as I like to know whether or not a cast is valid.

The mapping table from Foo to float and Bar to int should be in one place and expressive. So here is how default_cast could look like:

1
2
3
4
5
6
7
8
template<typename T>
decltype(auto) default_cast(T& t)
{
  return MapType<T, 
                 V<Foo, float>, 
                 V<Bar, int>
                >(t);
}

As you can see, it contains the mapping table. Line 5 and 6 are two table entries declaring that the default for Foo should be float, whereas for Bar the default is int. Looks promising. The type V is a very simple struct just capturing the in and out type:

1
2
3
4
5
6
template<typename InTypeT, typename OutTypeT>
struct V
{
  using InType  = InTypeT;
  using OutType = OutTypeT;
};

So far so good. How does the function MapeType look like? Of course, it is a template function. Its job is to take the type T and try to find a match for in the list of Vs. Sounds a lot like a variadic template job. Here is a possible implementation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
template<typename T, typename C, typename... R>
decltype(auto) MapType(T& t)
{
  if constexpr(is_same_v<T, typename C::InType>) {
    return static_cast<typename C::OutType>(t);
  } else if constexpr(is_same_v<
                        T,
                        const typename C::InType>) {
    return static_cast<const typename C::OutType>(t);
  } else if constexpr(0 == sizeof...(R)) {
    return t;
  } else {
    return MapType<T, R...>(t);
  }
}

It is based on a C++17 feature: constexpr if. With that the mapping is done at compile-time. With the help of variadic templates MapType expands at compile-time looking for a matching input type in the variadic argument list. In case a match is found, the output type is returned with a static_cast to the desired default output type. In case no matching type is found MapType pops one V-argument and calls itself again. The nice thing with C++17 and constexpr if is, that I can check for the last case where no more arguments are available. Plus it allows me to have mixed return types in one function, as all the discard branches are ignored.

How to handle the case where no mapping exists is up to the specific environment. Here I just pass the original type back. However, this hides some missing table entries. At this point a static_assert could be the better thing.

This construct generates the same code as I could write it by hand. Just way more deterministic. And here is how default_cast is applied:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
void After()
{
  Foo foo{1.0f};

  auto floatFoo = default_cast(foo);

  printf("%f\n", floatFoo);

  Bar bar{2};

  auto intBar = default_cast(bar);

  printf("%d\n", intBar);
}

Especially with C++11's auto the static_cast's in code I've seen and written increased. auto captures the original type and does care for conversions. default_cast is a convenient way to stay safe and consistent with less typing. Still transporting the message, that a cast happens intentionally at this point.

Have fun with C++17 and all the new ways it gives us.

Andreas

New article: "About the C++ Core Guidelines"

C++ is for sure not the easiest language to learn and to use. The Core Guidelines try to provide some useful directions in how to avoid common traps and pitfalls occurring with using C++. In the end they are still guidelines and need to be tailored to custom needs. I wrote an article for ACCU's overload  journal "About the C++ Core Guidelines" which just got out.

Here is a short teaser:

"In 2015 at CppCon, Bjarne Stroustrup announced the C++ Core Guidelines [CCG] in his opening keynote. These guidelines are a summary of best practices intended to overcome known traps and pitfalls of the C++ programming language. All the rules are grouped into several sections ranging from philosophy, interfaces and classes to performance and concurrency. The project is designed as an open source project, which should ensure that it will improve over time along with the language itself."

I'd like to say a huge thank you to Peter Sommerlad (@PeterSommerlad) for his comments to the draft versions.

Check out and enjoy issue 140.

Andreas

NDC { Oslo } slides and video available

I noticed yesterday that the video my presentation at NDC { Oslo } in June is available youtube:



Actually, aside of youtube the conference organizers decided to upload it to vimeo as well. It's up to you to decide on which platform you enjoy watching it most.

You can find the slides of this talk at my talks and training page a couple of days ago. This site also contains details for my other public appearances.

I hope you enjoy the material. Happy viewing!

Andreas

Article "Nutzen Sie die Macht der Sprache" got published

My article I wrote for the proceedings of the ESE Kongress 2016 got published at embedded software engineering.

It opens a view inside my talk Nutzen Sie die Macht der Sprache where I try to encourage people to use not only the tip of a programming languages iceberg but instead use the whole language. Write clear, readable and maintainable code.

The amazing picture you can see there was drawn by Franziska Panter (@FranziskaPanter) from panther concepts. I like her hand drawing style. That's why all my images are currently from her. All images are hand drawn and at the same time are fully digital, this means you can get vector images or vector PDFs. This is possible with the awesome technology we have nowadays.

I hope you find the article both interesting and inspiring.

Andreas

Keynote at Clean Code Days in Munich on June 21st

I will giving this years keynote at the Clean Code Days in Munich. The title of the talk is "Use the power of the language". I will use C++ as an example programming language to show how and why it matters to produce clean, clear and readable code. This topic is specially important in the embedded software domain where code tends to live for a very long time. However, clean, clear and readable code is valuable in all areas.

Be aware, this time the title is misleading. The language is most likely to be German. It depends on the audience, which will presumably be German. However, the final decision will be made shortly before the talk.

For other appearance of me, check out my "Talks and Training" page.

I hope to see you in Munich!

Andreas

New seminar: C++1x für eingebettete Systeme kompakt

This year I'll be working with QA Systems for a one day technical seminar called C++1x für eingebettete Systeme kompakt. The seminar will be in Stuttgart November 21st. The language of the seminar is as the title suggests, German.
There is an early bird discount, if you register before August 21th. The class size is limited to about 20, so that I'll be able to interact with the attendees directly. To register, visit http://www.qa-systems.com/academy/register/new-c-1x-fuer-eingebettete-systeme-kompakt/.
You'll find links to the details for all my public appearances at my talks and training page or for this particular one also at my partner's site.

I look forward to see you there.

Andreas