You are currently browsing the archives for the C/C++ Programming category.

Demystifying C++ lambdas

March 7th, 2014

A new (but not so welcome?) addition

Lambdas are one of the new features added to C++ and seem to cause considerable consternation amongst many programmers. In this article we’ll have a look at the syntax and underlying implementation of lambdas to try and put them into some sort of context.

Read more »

goto fail and embedded C Compilers

February 27th, 2014

I can’t imagine anyone reading this posting hasn’t already read about the Apple “goto fail” bug in SSL. My reaction was one of incredulity; I really couldn’t believe this code could have got into the wild on so many levels.

First we’ve got to consider the testing (or lack thereof) for this codebase. The side effect of the bug was that all SSL certificates passed, even malformed ones. This implies positive testing (i.e. we can demonstrate it works), but no negative testing (i.e. a malformed SSL certificate), or even no dynamic SSL certificate testing at all?

What I haven’t established* is whether the bug came about through code removal (e.g. there was another ‘if’ statement before the second goto) or, due to trial-and-error programming, the extra goto got added (with other code) that then didn’t get removed on a clean-up. There are, of course, some schools of thought that believe it was deliberately put in as part of prism!

Then you have to query regression testing; have they never tested for malformed SSL certificates (I can’t believe that; mind you I didn’t believe Lance was doping!) or did they use a regression-subset for this release which happened to miss this bug? Regression testing vs. product release is always a massive pressure. Automation of regression testing through continuous integration is key, but even so, for very large code bases it is simplistic to say “rerun all tests”; we live in a world of compromises.

Next, if we actually analyse the code then I can imagine the MISRA-C group jumping around saying “look, look, if only they’d followed MISRA-C this couldn’t of happened” (yes Chris, it’s you I’m envisaging) and of course they’re correct. This code breaks a number of MISRA-c:2012 rules, but most notably:

15.6 (Required) The body of an iteration-statement or selection-statement shall be a compound-statement

Which boils down to all if-statements must use a block structure, so the code would go from (ignoring the glaring coding error of two gotos):
Read more »

The hokey-cokey* of function calls

January 20th, 2014

Functions are the lifeblood of a C program. The program flow is altered by passing parameters to functions, which are then manipulated. Conceptually function parameters are defined as being either:

  • Inputs (Read-only) – client-supplied objects manipulated within the function only
  • Outputs (Write-only) – objects generated by the function for use by the client.
  • Input-Outputs (Read-Write) – client objects that can be manipulated by the function.

Defining the use of a parameter gives vital information not only to the implementer, but (perhaps more importantly) to the user of the function, by more-explicitly specifying the ‘contract’ of the function.

Many programming languages (for example, Ada) support these concepts explicitly. C, however, does not. One has to remember that when Kernighan and Ritchie developed C structured programming was very much in its infancy and many of these ideas were still being formulated (also remember that one of the C design goals was parsimony).

Even today, though, these concepts are rarely taught to C programmers and that has often led to clumsy, insecure or even downright dangerous APIs.

If C doesn’t support these concepts explicitly, can we simulate them? The answer is (of course) yes, by using some basic language constructs and forming some idioms.

Let’s look at each parameter type in turn.

Input parameters

C specifies a call-by-value or call-by-copy paradigm. That is, when a C function is called the compiler sets up a call frame that holds copies of the function parameters. Therefore, when you pass parameters by value you are – in effect – creating a parameter for the function to use that in no way affects the caller’s data

image

This is fine for simple types, but what about user-defined types – structs? What’s the problem with passing them by value?

image

Passing a structure by value means allocating enough memory for the parameter and then copying the contents of the original object into the parameter. In many embedded systems, where memory is at a premium, this could easily overflow the stack – at run-time, where its consequences could be difficult to track.

Strictly, to be explicit you should specify the type of the parameter as a const:

image

For simple types this is unlikely to add much value; however it may provide some benefit with structures.

If a parameter is passed as a const struct the compiler has the opportunity to perform a lazy evaluation – it passes the address of the structure instead of making a copy.

image

Note that this optimisation may not be supported by all compilers; or might not occur at all levels of optimisation.

Input-Output parameters

The resolution to the above problem is to explicitly pass a pointer to the structure:

image

This is clearly more efficient than copying the whole structure. OK, the syntax has got a little messier, but we can live with that.

But hang on: do we still have an Input parameter? Actually, no.

What we’ve got here is an input-output parameter. By passing a ‘raw’ pointer the function can manipulate the caller’s object. To fix this we need to prevent manipulation of the pointed-to object:

image

Still not quite there, though. What happens below?

image

Strictly we should make the pointer itself const to prevent (either accidently or maliciously) the function manipulating the caller’s object:

image

This is a very good general rule-of-thumb for functions: make all pointers const

Output parameters

An output parameter is one that the function can write to, but never read (i.e. write-only). In C the only real mechanism we have for that is the function return value.

Most programmers are happy to return simple types from functions but what about the following code?

image

Since C performs pass (and return!) by value this would appear very inefficient:

image

The original object (biiig) is constructed. Then, when makeBigStruct is called space for the return value is allocated. Inside makeBigStruct, temp is allocated. On return temp is copied into the return value then, finally, copied into biiig.

Knowing this, most programmers never return structures from functions; preferring instead to supply them as input-output parameters. However, most modern compilers provide an optimisation which does just this.

Below is the same code but showing the optimisation. Instead of returning the structure the address of the receiving object is (implicitly) passed to the function. At the end of the function the return value is copied into the receiver, negating the need for a temporary return object.

image

In general, then, it is OK to return a struct from a function by value (unless you’re using an ancient C compiler). If you’re not certain (or your compiler doesn’t support this optimisation) it’s probably safer for you to use input-output parameters instead.

Finally, it’s worth noting the small detail that, unlike other languages, a C function can only have one output parameter. You’ll need to use input-output parameters for the rest.

Making the world a better place.

Using these idioms consistently is a very good way to improve the quality of your code. Firstly, it allows the compiler to provide stronger checking on your code. Second, it gives the reader extra information about how to use your functions and what guarantee (or promise) they can expect from them.

You may have noticed I’ve ignored arrays in this article. Check out this blog post for passing arrays to functions.

In summary:

image

 

* Or, hokey-pokey if you prefer.

Shock horror! I learned something about arrays in C

November 28th, 2013

Every so often you pick up a snippet of information that completely changes the way you view things. This week, it’s the use of arrays as function parameters.

At first glance the code horrified me (as I’m sure it will horrify some of you out there!) but as I’ve played with it I can see real merit in the technique.

Arrays, pointers and syntactic sugar

In C there is a close (if somewhat messy!) relationship between arrays and pointers. As far as the C compiler is concerned an array is merely a contiguous sequence of objects (all of the same type). Pointer arithmetic semantics ensure that elements can be accessed as offsets from the array’s base address. The array (‘[]’) notation is syntactic sugar to hide these details from the programmer:

image

Arrays as function parameters

When passing arrays to functions (as parameters) things can get a little confusing. It is not possible to pass an array by-value to a function, so the function process_array() below does not make a copy of the array:

image

The array parameter degrades to a pointer – the address of the first element; so we could (and many C programmers do) just as legitimately write the following and get the same result:

image

In fact, all these declarations for process_array() are semantically identical; the code generated is the same in each case:

image

A word of warning here: as we discussed above the array name yields a constant value that is the address of the first element. In the case of a function parameter, though, we could easily delude ourselves:

image

What looks like an array name is (of course) just a (non-const) pointer; which can be modified, either deliberately or accidently.

Once inside our function, very commonly we wish to know the number of elements in the array. The sizeof() operator yields the amount of memory an object occupies; so for an array this is the number of elements times the size of the element. A simple piece of macro programming can yield the number of elements:

image

However, within our function we may not get the answer we expect:

image

In a 32-bit architecture we’ll always get an answer of 1, irrespective of the actual number of elements in the array!

If we re-write the function to the (semantically-identical, remember!) equivalent and expand the macro:

image

We’re dividing the size of a pointer by the size of an int. Oops.

Because of this it is normal practice to pass an additional parameter, the number of elements in the (supplied) array:

image

Is there any other way?

An alternative (I’m loathe to use the word ‘better’ here) approach is to use the mechanism preferred for all large data types – pass-by-pointer.

The syntax for passing an array by pointer is a little unwieldy due to C’s precedence rules:

image

The function signature declares that process_array() is expecting a pointer to an array of (exactly!) 10 uint32_t objects.

To call the function, you must pass the address of the array (just as you would with a struct):

image

This may cause confusion for some readers – They’re thinking “Hang on! The array name yields the address of the array!  Why isn’t he just calling the function with the name of the array?”.  Remember: the array name yields the address of the first element (and will be, in our case, of type uint32_t*).  We need a pointer to an array (of 10 uint32_t) so we must use the address-of operator (which will yield a pointer of type uint32_t ( * )[10]). 

The array-pointer is strongly typed, so the following code will fail to compile:

image

In case you were wondering, the following code will now work as expected (although, since you are specifying the expected size of the array it is a little redundant):

image

Although unusual for arrays (that is, not used often) this approach has a number of benefits:

  • The function declaration explicitly states the size of the array it is expecting.
  • It allows compile-time type checking
  • It is consistent with passing structs
  • The ARRAY_SIZE macro can be used on the function parameter (correctly)

The above code is actually the preferred mechanism for passing arrays in MISRA-C++ 2008 (Rule 5-2-12) but is not included in the MISRA-C 2012 rules (for some reason).

Casting – what could possibly go wrong?

September 27th, 2013

Type casting in C++ is a form of what is known in computer science as type punning – that is, circumventing the type system of a programming language.

C++ inherits its conversion and casting mechanism from C, but supplements it (although sensibly we should say, replaces it) with four, more explicit cast operations:

  • static_cast
  • reinterpret_cast
  • const_cast
  • dynamic_cast

In C and C++ – and particularly in embedded systems – casting is a necessary evil; so much so that many programmers just accept it as part of everyday programming practice.

So then: why is casting ‘evil’? Basically, because every time you do a type cast you are opening up your program to potentially unpredictable or unexpected behaviour. Let’s have a look at the four type-cast operators and the fun and games they can unleash on the unsuspecting.

 

static_cast<>

The static_cast operator converts between different object types; for example between a double and an int. So what you are effectively saying is

“I’m about to squeeze a big object into a smaller one, so you should probably make sure the receiving object is big enough to hold the values it’s going to get.”

Or:

I’m about to force a floating point number into an integer and all those decimal places (that are probably quite important) are going to be lost”

Of course, you could also be saying:

“I’m about to put the contents of a small object into an object capable of holding much larger values (or with greater precision)”

(which is emphasising a bit of a non-problem, really)

Thankfully, C++ doesn’t let you type-cast between different class types unless you’ve defined your own explicit conversion functions (which – hopefully – should do a sensible conversion). But that’s for another time.

 

reinterpret_cast<>

reinterpret_cast is used in two ways:

  • To convert a pointer-to-type into a pointer-to-different-type
  • To convert an integer type to a pointer type; or vice versa.

When reinterpret_cast appears in code it tells the reader:

“I’m going to take the object address you gave me and treat it as a completely different type, with different memory layout and different behaviour(s). You should make sure it’s capable of supporting what I want to use it for.”

Or, in another usage:

“That (random) number you gave me? I’m going to use it as the address of an object. You’d probably better make sure it’s a valid address, in a reachable region of memory; unless you’re a big fan of segmentation faults.”

 

const_cast<>

The const_cast operator removes the const-ness of an object; that is, it makes a read-only object writeable.

Significantly for embedded programmers, const_cast removes any cv (const-volatile) qualification the original object may have. This means a volatile object – for example, one used to represent a hardware register in an embedded system – can have that qualification removed with const_cast.

Using const_cast says:

“The object you didn’t want me to change? I might (accidently) change it without your consent.”

Or, perhaps in an embedded system:

“The compiler might now optimise away any reads or writes to that object you gave me. Be prepared for behaviour NOT to happen as you expect!”

 

dynamic_cast<>

The dynamic_cast operator is a special case here, in that it is used for ‘safe down-casting’ – that is, casting a pointer-to-base-type to a pointer-to-derived-type, whilst checking whether this is, in fact, a valid cast. dynamic_cast uses Run-Time Type Identification (RTTI) to ensure the types of the pointers are valid. Thus, unlike the other cast operators, dynamic_cast is a run-time check and has associated overheads. If the pointer types are not compatible dynamic_cast returns 0 (for pointers) or throws an exception (for references).

dynamic_cast also has a role in multiple inheritance, where a class has two or more base classes. The dynamic_cast operator allows you to cast a pointer of one base class type to another. Although this is basically a variation on safe down-casting we tend to use the term ‘cross-casting’. Cross-casting is commonly encountered when a class realises (inherits from) two or more interface (pure virtual) classes.

In your code this means:

“I need to access the extended interface of a particular derived type. You’d better be prepared to deal with the consequences of the derived type NOT being what I want.”

Or:

“I need to know if the object you’ve supplied supports some other – possibly completely different – set of characteristics. ”

 

So – don’t use type casts?

Obviously, it’s impracticable (if not impossible) to write code with no type casting; especially in embedded systems. I leave you with the following guidance:

  • Don’t cast if you don’t need to.
  • Think about the consequences of what the cast is (potentially) doing.
  • Leave a big, obvious comment documenting why we’re doing something so potentially dangerous.

The Rule of the Big Five

September 13th, 2013

The dynamic creation and destruction of objects was always one of the bugbears of C. It requires the programmer to manually control the allocation, initialisation and deallocation of memory for the object. 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 with an idiom known as RAII/RRID; more generically referred to as resource management. Resource management frees the client from having to worry about the lifetime of the managed object, potentially eliminating memory leaks and other problems in C++ code.

However, introducing resource management can lead to potential problems, particularly if the ‘manager’ objects are passed around the system. These problems led to the need for establishing a ‘copy policy’ for each of your types, sometimes referred to as ‘The Rule of the Big Three’. C++11 further complicated this by introducing move semantics.

This whitepaper explores the copy and move semantics of C++ and introduces a policy we call ‘The Rule of The Big Five’.

The whitepaper can be downloaded from here

Example source code for Visual Studio 2012 and GCC can be downloaded from GitHub.

ARM TechCon 2013

August 15th, 2013

ARM’s Technical Conference called TechCon™ is running between October 29th and 31st at the Santa Clara Convention Center in California.

Logo

This year I shall be making the trip over to present three classes:

For those of you who are regular readers of this blog you’ll recognise the Generic Hard-Fault Handler from a previous post.

The class “Can Existing Embedded Applications Benefit from Multicore Technology?” came about as it seemed that not a day would goe by without an announcement of a major development in multicore technology. With so much press about multicore, I started to wonder whether I should consider using multicore technology in my typical embedded applications? 

From a software developer’s perspective, however, all the code examples seem to demonstrate the (same) massive performance improvements to rendering fractals or ray-tracing programs. The examples always refer to Amdahl’s Law, showing gains when using, say, 16 or 128 cores. This is all very interesting, but not what I, and hopefully most embedded developers, might consider embedded. This class discusses multicore from a more traditional embedded viewpoint.

Many Embedded-C programmers still believe that C++ leads to slow, bloated programs. Though this viewpoint may have had limited foundation over a decade ago, it is misplaced for the core aspects of C++ (classes, inheritance, and dynamic polymorphism). With a modern ARM C++ cross-compiler, it is also misplaced for the more advanced features (templates and exception handling). In the class “Virtual Functions in C++ on the ARM Architecture”, I will be focusing on the performance and memory of the C++ virtual functions, type info and look at the use of multiple inheritance in an ARM embedded environment.

If you are planning to attend TechCon this year then please look me up. I will be making the presentations available via the blog after the event.

Niall.

Namespaces

July 12th, 2013

In this article we look at one of the issues inherent in C when building larger projects – the problem of function and object naming. We look at the C++ solution to this: namespaces.

A problem with big projects in C

When we move to multi-file projects the problem in C is having to create unique names for functions and externs in the global namespace. If we don’t have unique definitions this will lead to a link-time error.

We could, of course, make the functions static but then they are only available within the file they are defined in.

image

A common solution to the problem amongst C programmers is to add an extension to the function name to make it unique. Very commonly this is the module name.

This works for your own code but is often not an option for third-party code:

image

The C++ answer: namespaces

A namespace is a named scope. A user-defined namespace is a mechanism for expressing logical grouping in your code.

image

By putting the classes Longitude and Latitude into the namespace Nav we have effectively extended their names by ‘prefixing’ them with the namespace name.

In the implementation file we must prefix the namespace name onto the class (using the scope resolution operator) when we define the member functions (or indeed any other member). An alternative notation is to enclose all the class definitions within a namespace declaration.

image

Elements defined within a namespace can be accessed in any of three ways:

  • by using the fully qualified name, in this case Nav::
  • If the item is used a lot, then it can individually be brought into the global namespace with the using directive.
  • The global statement using namespace Nav makes all names in the namespace available

image

Namespaces are an open scope – it is possible to keep adding definitions to the namespace, across different translation units.  Although classes act as namespaces they are referred to as a closed scope – that is, once a class (namespace) has been defined it cannot be added to.

image

It is good practice to put all code into a namespace, rather than leaving it in the global namespace. The only thing that should (ideally) be in the global namespace is main(). (MISRA-C++ makes this demand of you.)

Namespace hierarchies

Namespaces may be nested arbitrarily deep. Nested namespaces are analogous to a hierarchical file system, rooted in the global namespace (which is identified by having nothing to the left of the scope resolution operator (::)

image

If your coding standard demands that you explicitly qualify type names then having hierarchies of namespaces (each with a descriptive name) can quickly become onerous, and lead to less-than-readable code. To improve legibility C++ allows namespace aliasing. A namespace alias is a – usually shorter and more succinct – synonym for the declared namespace.

image

 

Forward references and namespaces

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

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 (a Sensor object, in this case) or access any of its member variables or operations. 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).

However, if we put our Sensor and Actuator classes in a namespace we have a problem. In the case of the Positioner class, above, since we are only declaring pointers to Sensor and Actuator objects it is good practice to use forward references to those classes.

The syntax, as shown below, looks reasonable but doesn’t work.

image

The compiler takes the forward reference as referring to a nested class; it cannot know IO is a namespace.

The solution is to tell the compiler that IO is a namespace with the namespace keyword. The forward references to Sensor and Actuator can then be declared within the namespace.

image

 

Argument-dependent lookup

Remember from previously, if we want to use a class or function from a namespace we have to explicitly fully-qualify the entity. If this is true (and it is) then the following code shouldn’t compile:

image

The reason it should fail is the overloaded operator<<. This is actually a function call which, like everything else in the Standard Library, placed in the namespace std

std::ostream& std::operator<< (std::ostream&, const char*);

This means that, in order to access this function, we should have to fully qualify its name:

image

This is not very readable; and, of course, we know the original code does compile perfectly fine.

The solution is a compiler mechanism called Argument-Dependent Lookup (ADL) or Koenig Lookup (after its inventor, Andrew Koenig). ADL states that if you supply a function argument of class type, then to find the function name the compiler considers matching names in the namespace containing the argument’s type.

image

In the example above we have defined a class, Digital and an overloaded function doStuff in the namespace Points.

When we make a call to doStuff() with a Points::Digital object the compiler is able to look into the owning namespace of Digital (Points::) and find a function with the correct signature.

However, this only works with arguments of class type so the call to doStuff() with an integer cannot be resolved automatically; the programmer would have to explicitly qualify the function

Points::doStuff(10);

Our earlier Standard Library example can now be explained: since one of the parameters of std::operator<< is of class type (in this case std::ostream) the compiler can search the std:: namespace for an appropriate function signature without the programmer having to explicitly qualify it. The simplification of library code like this is the primary reason for the inclusion of ADL.

Useful though this is, ADL has the potential to cause us problems in our code. Consider the example below:

image

Here, the call to doStuff() is ambiguous – it could be either Feabhas::doStuff(Points::Digital&) or Points::doStuff(Points::Digital&) (using ADL). There is no automatic resolution – the programmer must explicitly qualify the call with the appropriate namespace name to get the doStuff() they want.

 

Preserving the locality of code

In C, the keyword static has two sets of semantics, depending on where it used. The keyword static can be applied to functions and variables

Functions

Static functions are not exported, they are private to the module they are defined in. They have internal linkage; they do not appear in the module’s export table. This is useful for preventing your local helper functions from being called outside of your module.

Variables

Applying static to objects defined outside any block (confusingly, called ‘static objects’ in the standard!) gives the object internal linkage. The static object is visible anywhere in the translation unit, but not visible from any other translation unit.

When an automatic (local) variable is marked static in a function the compiler allocates permanent storage for it (at compile time). Practically, this means it retains its state between calls to the function but its scope is limited to the function in which it is defined.

C++ extends this behaviour to user-defined (class) types as well.

image

However, C++ prefers the use of a concept called an un-named namespace instead of static to give objects and functions internal linkage.

image

An un-named namespace is (as the name suggests!) an anonymous namespace – it does not have a name. The compiler allows entities (objects and functions) in this namespace to be accessed within the defining translation unit, but not outside. Un-named namespaces in different translation units are considered independent (and different). There is no way of naming a member of an unnamed namespace from another translation unit; hence the members of that namespace cannot be accessed (making them, effectively, static).

This removes the need for C’s static, which has now been deprecated (meaning it is currently supported, but likely to be removed from the next revision of the standard.)

 

Conclusion

Namespaces are a powerful organisational tool in your design. They are a compile-time construct so have no run-time overhead. There’s no good reason not to use namespaces in your code. They will help you build more maintainable, more portable and more reusable code.

For more, even more exciting exploration of this topic have a look here:

http://www.gotw.ca/publications/mill02.htm

http://www.gotw.ca/publications/mill08.htm

Style vs. Substance in C programming

June 21st, 2013

In an email from UBM Tech this week there was a link to an article titled “A Simple Style for C Programming by Mansi Research“. It was actually authored back on May 2010 by Meetul Kinariwala but appeared this week under the what’s hot section, so I thought I’d take a look [advice to the reader; don't bother].bad-clothing_16

The problem with guides like this is that style is a very subjective area (as any parent will tell you how their kids like to point out your lack of style). Programming is no exception and you could argue with C being such a compact language, it suffers more than many other languages.

One of the many good things about the MISRA-C guidelines is that it clearly separated out the issue of style vs. coding guidelines, i.e. [Guidelines for the Use of the C Language in Critical Systems, ISBN 978-1-906400-10-1, page 9]

5.2.2   Process activities expected by MISRA C
It  is  recognized  that  a  consistent  style  assists  programmers in understanding  code  written  by others. However, since style is a matter for individual organizations, MISRA C does not make any recommendations related purely to programming style. It is expected that local style guides will be developed and used as part of the software development process.

I couldn’t have put it better myself.

Clearly for larger teams a style guide is a useful and important part of the development process.

A whole host of style issues can be addressed with a “pretty printer” tool such as Artistic Style. These simply allow you to define a standard model for items such as ‘{‘ alignment, tab-to-space ratio and spacing within expressions [e.g. if (a&&b) vs. if ( a && b ), etc.].

However there are many style issues that can’t be addressed with automation, for example naming convention. People of a certain age will have been unfortunate enough to have to use Hungarian notation, which, at its roots, had a good underlying principle (embedded type information in the name). That said, Hungarian notation is, in my opinion, an abomination.

One of those coding styles that always make me want to spit feathers is putting a literal on the left of a comparison expression, e.g.
if (10 == var)
I know, you think it’s a great idea as it stops you accidentally writing:
if(var = 10)

Yes it does, but that also tells me you’re not using any form of static analysis tool (e.g. PC-lint, Coverity, QAC, etc.) which means you’ve got much bigger problems that accidentally assigning 10 to the variable!

My major issue is that, for someone who ends up reviewing a lot of other people’s code, it acts as a mental ‘speed bump‘; I wouldn’t say “if ten is equal to var?“‘ I’d say “if var is equal to 10?“, so why write it that way? Surely we want to make code a readable as possible and I’d argue (10 == var) is just ‘bad‘ style.

Probably the biggest issue I regularly come across is that most company coding standards

  • do not differentiate between rules that are there for safety/security reasons (e.g. Functions shall not call themselves, either directly or indirectly) and rule purely for style (e.g. for pointer variables place the * close to the variable name not pointer type)
  • do not have automation of rule checking; if it’s not autometed it won’t get enforced.

As I’ve already said, I’m not against coding style guidelines, quite the contrary I think, when well done, they aid code readability across a project/company. But what’s really needed is a coding meta-style guide (i.e. a guide to what a coding style guide should address).

For example, a coding style guide should consider the structure of a C file, e.g. ordering items within a file based on some defined criteria, such as:

  • Context then definition
  • External then Internal
  • Public then Private
  • Functional grouping
  • Type grouping
  • Alphabetic sorting

The meta-style-guide tells you that you should consider file structure; the actual-style guide tells you, for you project, how a C file should be structured.

Googling the web hasn’t thrown up any meta-style guides, so here at Feabhas we’re undertaking to develop an open, community driven, meta-style guide. We haven’t defined the best model yet (github, google+, etc.), but as soon as we do I’ll ensure it’s published here.

In the meantime feedback/comments on the meta-guide would be welcome.

UPDATE
I have subsequently come across the following resource that is a great meta-guide C Style: Standards and Guidelines and I highly recommend a visit.

Test Driven Development (TDD) with the mbed

May 24th, 2013

One of the most useful fallout’s from the acceptance of Agile techniques is the use of Test-Driven-Development (TDD) and the growth of associated test frameworks, such as GoogleTest and CppUTest, etc.

I won’t get into the details of TDD here as they are well covered elsewhere (I recommend James Grenning’s book “Test Driven Development for Embedded C” for a good coverage of the subject area), but the principle is

  1. Write a test
  2. Develop enough code to compile and build (but will fail the test)
  3. Write the application code to pass the test
  4. repeat until done

Obviously that is massively simplifying the process, but that’s the gist. The key to it all is automation, in that you want to write a new test and then the build-deploy-test-report (BDTR) cycle is automated.

To build a TDD environment with the mbed I needed to solve the following obstacles:

  1. Build – Using a TDD framework and building the project
  2. Deploy –  Download to the mbed
  3. Test – auto-executing the test code on the mbed
  4. Report –  Getting test reports back from the mbed to the host

Read more »

%d bloggers like this: