The Rule of Zero

January 15th, 2015

In a previous article – ”The Rule of the Big Four (and a half)” we looked at resource management policies in C++.

Resource management is the general term for using the mechanisms in C++ to ensure that resources – files, dynamic memory, sockets, mutexes, etc – have their lifetimes automatically controlled so as to prevent resource leaks, deadlocks, etc. C++ refers to these mechanisms as RAII/RDID ( “Resource Acquisition Is Initialisation / Resource Destruction is Deletion”)

In this article we’ll have a look at a complementary guideline to help simplify your application code, without risking resource management issues – The Rule of Zero.

Read more »

The Rule of The Big Four (and a half) – Move Semantics and Resource Management

January 1st, 2015

In the previous article we looked at the issues of resource management in C++ and introduced “The Rule of The Big Three (and a half)”. In this article we’ll extend this concept by looking at the idea of move semantics, a feature introduced in C++11. Move semantics mean we’ll have to extend our rule to “The Rule of The Big Five” or, perhaps more correctly, “The Rule of The Big Four (and a half)”.

Read more »

The Rule of The Big Three (and a half) – Resource Management in C++

December 18th, 2014

The dynamic creation and destruction of objects was always one of the bugbears of C. It required the programmer to (manually) control the allocation of memory for the object, handle the object’s initialisation then ensure that the object was safely cleaned-up after use and its memory returned to the heap. Because many C programmers weren’t educated in the potential problems (or were just plain lazy or delinquent in their programming) C got a reputation in some quarters for being an unsafe, memory-leaking language.

C++ improved matters significantly by introducing an idiom known (snappily) as RAII/RRID – Resource Acquisition Is Initialisation / Resource Release Is Destruction*. The idiom makes use of the fact that every time an object is created a constructor is called; and when that object goes out of scope a destructor is called. The constructor/destructor pair can be used to create an object that automatically allocates and initialises another object (known as the managed object) and cleans up the managed object when it (the manager) goes out of scope. This mechanism is generically referred to as resource management.

In this article we’ll explore resource management in C++ and introduce “The Rule of The Big Three (and a half)”.

Read more »

Software Duct Tape – Binding the C++ Universe Together

December 4th, 2014

One of the cornerstones of object-oriented design is the concept of objects interacting by sending messages to form mechanisms – units of higher-order (or ‘emergent’) behaviour.

In order to send a message (in this case, invoke a member function) an object must have a ‘link’ to the target object. That link is formed by building in an association between the two classes as part of the type’s definition.

In this article we look at building associations between classes and forming run-time links so objects can communicate.

The basic principle

An association represents the ability of one object to send a message (invoke a function) of another. In order to do that the sending object must know the identity of the receiver.

The identity of an object is its address; therefore we must hold the address of the receiver. An association between two classes is therefore implemented as a pointer to that type.

We also need a ‘binding’ function to encapsulate the linking of the two objects.

Connected objects form a system

image

In a client-server relationship the client invokes the services of the server. The client sends messages to the server. That is, the client invokes the member functions of the server. This relationship is uni-directional. The server never calls the client’s member functions.

In a peer-to-peer relationship either object may invoke the operations on the other. That is, the relationship is bi-directional.

Note: Just because a member function returns a value does not make the relationship bi-directional. The association type is determined by who makes the member function calls, not the direction of data travel.

Client-Server 1:1 association

The simplest, and probably most common, form of association is the unidirectional client-server.

image

In this example the Positioner class is the client, with two (independent) server classes – Actuator and Sensor. Here the identities of the server objects are stored as pointers; the constructor is used as the binding function.

We form the link by binding the actual objects together at run-time. In this example we bind the Actuator object and the Sensor object by passing in the addresses of these objects to the Positioner constructor.

image

The Positioner can now invoke member functions on its associated objects by dereferencing its pointers.

Improving the interface

Since a reference is an alias for an (existing) object, taking the address of a reference is the same as taking the address of the original object.

image

Or, put another way: since a reference acts as an automatically-dereferenced (const) pointer, taking the address of a reference is semantically equivalent to:

&(*(&pos));

image

Passing by reference hides from the client the fact that the CameraStabiliser stores pointers internally. This is yet another form of encapsulation.

A quick aside: Why not use references for associations?

In this simple case you could – and many programmers advocate this – use a reference to the server object instead of a pointer. I prefer to use a pointer for a number of reasons:

  • A pointer specifies that I am holding the address (identity) of an object; references are a mechanism for efficient parameter passing in functions. Let’s use the language idioms correctly and consistently
  • Pointers can be used consistently for all association types; references can’t. See below for more on this.
  • Since references can’t be re-seated using a reference ‘fixes’ the association. There’s no way to associate objects differently later in the program. This precludes the ability to do substitution of specialised types at run-time. This dramatically limits the flexibility of your design.  You’re probably better off using a template instead.

While we’re talking about pointers: don’t be tempted to use smart pointers for associations. The problem with a smart pointer is that it’s designed for use with dynamically-allocated objects. As a client you can’t (and shouldn’t) know the storage specification of your server object. If the server object is stack-based when your association smart pointer goes out of scope it will try and call delete on the address of the object (for those who haven’t experienced this, trust me – it never ends well).

Associations are one of the very few valid uses of ‘raw’ pointers in a C++ program.

1:N unidirectional associations

When the association is one-to-many then a simple pointer does not suffice. We could use individual (named) pointers but this would be a clumsy solution (at best). In this case we use a std::array to hold the pointers (since the maximum number of Position objects is fixed, at 16).

image

The moveTo() function acts as a ‘bind’ function. It adds the address of the associated object to the track array.

image

Notice that in this case we can’t use references to hold the identity of the object because you can’t have an array of references.

1:* Unidirectional associations

It’s a relatively trivial extension to implement a one-to-many association: simply replace the fixed-size array with a dynamic container (for example a std::list)

image

Bi-directional 1:1 associations

If our association is bi-directional, then both classes need pointers. The problems come when you have to bind the objects together: which object gets built first?

image

If both classes need a pointer to the other in their constructors to work there is a cyclic dependency.

One solution is to provide a ‘binder’ function on each class that forms the association. In this example, the UI class has an additional member function, addStabiliser() that allows a CameraStabiliser object to be bound to it. The CameraStabiliser class has a complementary function.

image

At construction time, the CameraStabiliser and UI objects are constructed. Then the objects are bound together by calling the ‘bind’ functions. Notice, the programmer must ensure that the objects are bound together before they are used, otherwise you may end up dereferencing null pointers! Having to check for null pointers may seem a major drawback of this technique but it should be remembered that, sometimes, your design may actually require an unfulfilled association.  If that isn’t the case, using an assert in your code during development will highlight that you have failed to construct your system correctly.

A consequence of this approach is that the public interface of a class becomes ‘polluted’ with bind functions, which have nothing to do with the class’s functionality. This breaks the Single Responsibility Principle, which says an object should only have one reason to change. In this case, our classes have two reasons to change: their behaviour, which is part of their design; and their set of associations, which is a function of how they will be used in this particular project. These two aspects are orthogonal.  For example, the same class could be used in a very different way in another project, meaning it would most likely have a very different set of associations; even though its behaviour hasn’t changed.

An alternative approach is to create a free function that binds the two objects together.

image

Note, now both objects only have default constructors. The bind function forms the association between the two objects.

This approach has the benefit that it does not add any (non-behavioural) functions to the public interface of either class.

However, there is a problem with this code.

image

The bind function is not a member of either the UI or CameraStabiliser classes, so therefore cannot access their private data members (in this case, the association pointers)

Making the pointers public would allow this code to work but this exposes the pointers to clients and breaks encapsulation.

The solution is to make the bind function a friend function. A friend function is granted access to the private members of the class.

image

Notice the bind function must be made a friend of both the UI and CameraStabiliser classes.

The above is the general case for forming associations: a pointer plus a friend bind function. This will work for all associations – even the simplest case (1:1 unidirectional). For consistency of code this is the method I generally promote.

image

Reducing compile-time dependencies

Including one header file within another builds a dependency (coupling) between the two interfaces. Wherever possible we want to reduce the coupling between modules in our design.

image

In this case, including the class definition of class Sensor is unnecessary. You only need to include the class definition if:

  • You are going to allocate memory for an object
  • Inherit from an class
  • Call one of the class’s member functions.

Class Positioner does not instantiate a Sensor object; it merely has a pointer to a Sensor object. Since the compiler knows how much memory to allocate for a pointer we do not need to include the class definition of Sensor.

However, we must still declare that class Sensor is a valid type to satisfy the compiler. In this case we do so with a forward reference – actually just a pure declaration that class Sensor exists (somewhere).

image

Note: if we wish to call any of Sensor’s member functions we must include the class definition.

image

Summary

Adopting consistent idioms is the core of building maintainable code; making every construct a special case just makes code difficult to read, understand, extend and adapt.

In an object oriented design classes don’t just exist in isolation: they are inter-connected and their interactions are what provide the system’s behaviour. Understanding the need for, and implementation of, associations is a basic, fundamental skill for any C++ programmer.

 

If you’d like to know more about C++ programming – particularly for embedded and real-time applications – visit the Feabhas website. You may find the following of interest:

C++-501 – C++ for Embedded Developers

C++-502 – C++ for Real-Time Developers

AC++-501 – Advanced C++

AC++11-401 – Transitioning to C++11.

DP-403 – Design patterns for C++

On BashLite and Shellshock

November 19th, 2014

A number of people have been in touch with me about the fact that our Linux courses use an embedded target system that deploys BusyBox as standard and that there’s a “known exploit” doing the rounds called BashLite.SMB – this is obviously a cause for alarm!… Right?

WRONG!! Never one to shy away from defending my beloved Linux I wanted to make a quick public service announcement to say that this appears to be a fairly run-of-the-mill piece of malware riding on the coat tails of the significantly more dangerous ShellShock vulnerability which should be patched!

Busybox itself was never vulnerable to the Shellshock exploit due to it’s usage of an alternative shell – ash – which isn’t a bug-for-bug implementation of Bash.
BashLite is a backdoor opening, information stealing tool that can also be used as part of Command & Control based attacks and is typically the second prong of an attack that has already granted access to the system – either by ShellShock itself (you’re not running unpatched Bash on your device are you?) or by administrators and/or implementers deploying backdoored scanners to check their devices for ShellShock.

My advice is to keep devices off of the Internet during development, make sure they’re clean, keep your dev machines up-to-date with the latest patches, don’t ship devices that rely on components that have a history of bugs (and don’t expose said component via the web!), design and utilise an update strategy – preferably one that can be automated – and don’t trust everything you read on the internet!

If you’re really concerned about security and the types of attacks faced by embedded Linux users and how they work then I heartily recommend our new Secure Linux Programming course.

 

 

Acorn Goes to Market with RISC Microprocessor

November 6th, 2014

No I’ve not lost the plot, this was actually the headline from Electronics back in August 1985!

Recently my father was clearing out his loft at home and came across a couple of bagfuls of “rubbish” (garbage) which was full of various memorabilia from my degree days.  Among the various artefacts, to my great surprise, I came across a photocopy  of this article.

For those of you, like me, who were involved in electronics at that time, it’s a real trip down memory lane. Some of the notable snippets are:

Acorn’s ARM chip (for Acorn RISC machine)…

The ARM chip packs 25,000 transistors onto a small 50-mm² chip

The chip is about twice as fast as a VAX-11/780

Limited samples of the board [containing the ARM] are available for about $2000

For all those feeling nostalgic I have attached the original article for your enjoyment.

Page 1: Arm p1

Page 2: Arm p2

However, I’m guessing there is a whole swath of you who weren’t even born; they were the days and you don’t know how lucky you are, etc. (and all the other things old people say…)

Vulnerabilities in C : When integers go bad!

October 23rd, 2014

Insecure C?

weak_linkWe are at the dawn of a new era of connected embedded devices, broadly being marketed as the “Internet of Things” (IoT). The majority of these systems are likely to be programmed using C/C++. To date, much of the embedded world has been connected to propriety networks, however with the gold rush in to IoT we are not going to be able to rely on “Security through Obscurity“. This is the first in a series of articles looking at some of the vulnerabilities at the programming language level.

This and many other issues are covered in the Feabhas Training course Secure Linux Programming

Integral data types in C

Due, mainly to history, the integer types in C can be a little confusing, but for simplicity and brevity I’ll consider the core integral types to be:

  • char
  • short
  • int
  • long
  • long long

In reality, of course, a short is a short int, but for this discussion I’ll keep to the generally accepted model of referencing them as they’re shown above.

Next we can apply signness to the types:

  • unsigned
  • signed

Again for simplicity I’m going to assume that a signed int is using 2’s compliment representation. Even though the standard allows for “Sign and Magnitude” and “1’s compliment” I don’t know any (mainstream) modern compiler not using 2’s compliment[1].

Next we have to look at the underlying data models. The actual sizes of the data types are implementation defined in <limits.h>, but the implementation values must be greater than or equal to:

  • A char is a minimum of 8 bits
  • A short is a minimum of 16 bits
  • An int is a minimum of 16 bits
  • A long is a minimum of 32 bits
  • A long long is a minimum of 64 bits

Note the emphasis on the word “minimum”. However, it is also accepted that plain int’s “have the natural size suggested by the architecture of the execution environment”; thus on a 16-bit architecture a plain int would most likely be 16-bits, whereas on a 32-bit architecture they would be 32-bits.

For the remainder of this discussion I will base my examples around a “ILP32LL” architecture, meaning that the int, long and pointer are 32-bits, char is 8, short is 16 and long long is 64 (e.g. commonly found on ARMv7 architecture).

Ideally, to help reduce some of this confusion we should be using the C99 platform independent types from <stdint.h> and <inttypes.h>, but for now I’ll still reference the base types.

What are the potential underlying problems?

The problems with integers occur in a number of ways, significantly:

  • Overflow
  • Underflow
  • Promotion/extension
  • Demotion/narrowing
  • Sign conversion

with the behaviour of each issue being dependent of the underlying types

Read more »

Traits classes

September 18th, 2014

Introduction

In this final article we’ll have a look at the issue of communicating template type information between different template instantiations, and have a look at the Traits mechanism as a method of solving these issues.

Read more »

Template specialisation

September 4th, 2014

Introduction

Welcome back to the wonderful world of templates.

So far, we have looked at what are known as base templates. In this article we’re going to look at one of the more confusing aspects of templates – specialisation. The choice of the word specialisation is unfortunate, as many confuse it with inheritance and sub-typing; in this case specialised means “more specific”.

Read more »

Templates of templates

August 21st, 2014

Introduction

In this brief article we’ll have a look at the topic of building template classes whose parameters are themselves templates.

I’m assuming you’re reasonably familiar with template classes.  If not, here’s a quick introduction.

Read more »

%d bloggers like this: