Posts with «software development» label

Code Craft: When #define is Considered Harmful

An icon of Computer Science, [Edsger Dijkstra], published a letter in the Communications of the Association of Computer Machinery (ACM) which the editor gave the title “Go To Statement Considered Harmful“. A rousing debate ensued. A similar criticism of macros, i.e. #define, in C/C++ may not rise to that level but they have their own problems.

Macros are part of the preprocessor for the C/C++ languages which manipulates the source code before the actual translation to machine code. But there are risks when macros generate source code. [Bjarne Stroustrup] in creating C++ worked to reduce the need and usage of the preprocessor, especially the use of macros. In his book, The C++ Programming Language he writes,

Don’t use them if you don’t have to. Almost every macro demonstrates a flaw in the programming language, in the program, or in the programmer.

As C retrofitted capabilities of C++, it also reduced the need for macros, thus improving that language.

With the Arduino using the GNU GCC compilers for C and C++ I want to show new coders a couple of places where the preprocessor can cause trouble for the unwary. I’ll demonstrate how to use language features to achieve the same results more cleanly and safely. Of course, all of this applies equally when you use any of these languages on other systems.

We’re only going to be looking at macros in this article but if you want to read more the details about them or the preprocessor see the GNU GCC Manual section on the preprocessor.

Basic Macro Usage

The preprocessor is complex, but described in simplified terms, it reads each line in a compilation unit, i.e. file, scanning for lines where the first non-whitespace character is a hash character (#). There may be whitespace before and after the #. The next token, i.e. a set of characters bounded by whitespace, is the name of the macro. Everything following the name is the argument. A macro has the form:

#define <name> <rest of line>

The simplest macro usage is to create symbols that are used to control the preprocessor or as text substitution in lines of code. A symbol can be created with or without a value. For example:

#define LINUX 
#define VERSION 23 

The first line defines the symbol LINUX but does not give it a value. The second line defines VERSION with the value 23. This is how constant values were defined pre-C++ and before the enhancements to C.

By convention, macro symbol names use all caps to distinguish them from variable and function names.

Symbols without values can only be used to control the preprocessor. With no value they would simply be a blank in a line of code. They are used in the various forms of the #if preprocessor directives to determine when lines of code are included or excluded.

When a symbol with a value appears in a line of code, the value is substituted in its place. Here is how using a macro with a value looks:

const int version_no = VERSION; 

which results in the code

const int version_no = 23; 

This type of macro usage doesn’t pose much of a threat that problems will arise. That said, there is little need to use macros to define constants. The language now provides the ability to declare named constants. One reason macros were used previously was to avoid allocating storage for a value that never changes. C++ changed this and constant declarations do not allocate storage. I’ve tested this on the Arduino IDE, and found that C does not appear to allocate storage but I’ve seen mention that C may do this on other systems.

Here is the current way to define constants:

const int version = 23;
enum {start=10, end=12, finish=24};   // an alternative for related integer consts

Function Macros

Another form of macro is the function macro which, when invoked looks like a function call, but it is not. Similar to the symbol macros, function macros were used to avoid the overhead of function calls for simple sequences of code. Another usage was to provide genericity, i.e. code that would work for all data types.

Function macros are used to pass parameters into the text replacement process. This is fraught with danger unless you pay close attention to the details. The use of inline functions is much safer as I’ll show below.

To illustrate here’s an example of a function macro to multiply two values.

#define MULT(lhs, rhs) lhs * rhs

This function macro is used in source code as:

int v_int = MULT(23, 25);
float v_float = MULT(23.2, 23.3);

Consider this use of the macro, its expansion, and its evaluation, which definitely does not produce the expected result:

int s = MULT(a+b, c+d);
// translates to: int s = a + b * c + d;
// evaluates as: a + (b * c) + d

This can be addressed by adding parenthesis to force the proper evaluation order of the resulting code. Adding the parenthesis results in this code:

#define MULT(lhs, rhs) ((lhs) * (rhs))
int s = MULT(a+b, c+d);
// now evaluates as: (a + b) * (c + d)

The parenthesis around lhs force (a + b) to be evaluated before the multiplication is performed.

Another ugly case is:

#define POWER(value) ((value) * (value))
int s = POWER(a++);
// evaluates as: ((a++) * (a++))

Now there are two problems. First, a is incremented twice, and, second, the wrongly incremented version is used for the calculation. Here again it does not produce the desired result.

It’s really easy to make a mistake like this with function macro definitions. You’re better off using an inline function which is not prone to these errors. The inline equivalents are:

inline int mult(const int x, const int y) { return (x * y); }
inline int power(const int x) { return (x * x); }
 

Now the values of x and y are evaluated before the function is called. The increment or arithmetic operators are no longer evaluated inside the actual function. Remember, an inline function does not produce a function call since it is inserted directly into the surrounding code.

In C, there is a loss of generality using inline over the macro. The inline functions shown only support integers. You can add similar functions for different data types, which the standard libraries do, but the names must reflect the data type. A few cases would be covered by mult_i, mult_f,  mult_l, and mult_d for integer, float, long and double, respectively.

This is less of a problem in C++ where there are two solutions. One is to implement separate functions, as in C, but the function names can all be mult relying on C++’s ability to overload function names.

A nicer C++ version is to use template functions. These really are straightforward for simple situations. Consider:

template <typename T>
inline T mult(const T x, const T y) { return (x * y); }
template <typename T>
inline T power(const T x) { return (x * x); }

You use these just like any other function call and the compiler figures out what to do. There is still one minor drawback. The mult cannot mix data types which MULT has no problem doing. You must use an explicit cast to make the types agree.

The code generated by the inline and template versions are going to be the same as the macro version, except they will be correct. You should restrict the use of macros to preprocessing of code,  not code generation. It’s safer and once you are used to the techniques it’s easy.

If these problems aren’t enough, take a look at the GNU preprocessor manual section which provides more details and examples of problems.

Stringification and Concatenation

The previous sections discussed the problems with macros and how to avoid them using C/C++ language constructs. There are a couple of valuable uses of macros that we’ll discuss in this section.

The first is stringification which converts a function macro argument into a C/C++ string. The second is concatenation which combines two arguments into a single string.

A string is created when a # appears before a token. The result is a string: #quit becomes “quit”.

Two arguments are concatenated when ## appears between them: quit ## _command becomes quit_command.

This is useful in building tables of data to use in a program. An illustration:

#define COMMAND(NAME) { #NAME, NAME ## _command }

struct command commands[] =
{
COMMAND (quit),
COMMAND (help),
...
};

expands to the code

struct command
{
char *name;
void (*function) (void);
};

struct command commands[] =
{
{ "quit", quit_command },
{ "help", help_command },
...
};

Wrapup

The C/C++ preprocessor is powerful and dangerous. The standards committees have followed Stroustrup’s lead in adding features that reduce the need to use the preprocessor. There is still a need for it and probably always will be since it is an inherent part of the languages. Be careful when and how you use #define, and use it sparingly.


Filed under: Hackaday Columns, Software Development, software hacks

Arduino vs. Phidgets vs. Gadgeteer

A few days ago, we saw a dev time trial between the Arduino and Phidgets, a somewhat proprietary dev board that is many times more expensive than an Arduino. The time trial was a simple experiment to see which platform was faster to prototype simple circuits. As always in Hackaday comments, there was a ton of comments questioning the validity and bias of the test. Not wanting to let a good controversy go to waste, [Ian Lee] tossed his hat into the ring with the same dev trial with the Gadgeteer.

The Gadgeteer has the same design philosophy as Phidgets: modular components and a unique software system -the Gadgeteer is based on .NET Micro Framework – that allows you to get up and running quickly. Unlike Phidgets, the Gadgeteer is priced competitively with the Arduino, and the mainboard is priced within an order of magnitude of a single ATMega chip.

[Ian] pulled off three project with the three development platforms: blinking a LED, moving a servo, and building a pedometer with an accelerometer. For each trial, the time taken and the price of all components were added up. Here’s the relevant graph:

According to the tests, the Gadgeteer won by a large margin. We’re not going to call this a definitive test, and no sane person should think it is. It does, however, highlight the benefits of a well-designed ‘module-based’ development system combined with a good IDE: the Gadgeteer is consistently faster than Phidgets, and just a bit more expensive than an Arduino.

While a time trial consisting of one developer writing code to blink a LED, move a servo, and read a pedometer is hardly enough to make any conclusions, it does demonstrate that the Gadgeteer isn’t that much more expensive than using an Arduino. We’ll leave the rest of the discussion to the commentors below.


Filed under: reviews, Software Development

Arduino vs. Phidgets – Dev Time Trials

Is developing on an Arduino too slow? Are Phidgets too expensive? When might you use one or the other? Hackaday regular [Ken] breaks down what he learned from three experimental time trials.

The main development differences between Arduino and Phidgets are a mix of flavor preferences and some hard facts. The Arduino is open source, Phidgets are proprietary. Arduino requires a mix of hard- and software where Phidgets only needs (and only allows) a connection to a full computer but enables high level languages – it is expected to get the job done sooner and easier. And finally, Arduinos are cheap, Phidgets are 3-5x the cost.

The three time trials were common tasks: 1. Blink an LED. 2. Use a pot to turn a servo. 3. Build a pedometer. For [Ken], the Phidgets won in each of the three experiments, but not significantly: 37%, 45%, and 25% respectively. The difference is only minutes. Even considering time value, for most hackers it is not worth the cost.

In context, the advantages of a mildly more rapid development on the simplest projects are wasted away by needing to rebuild a permanent solution. Chained to a PC, Phidgets are only useful for temporary or fixed projects. For many of our readers that puts them dead in the water. Arduinos may technically be dev kits but are cheap enough to be disposed of in the project as the permanent solution – probably the norm for most of us.

[Ken] points out that for the software crowd that abhor electronics, Phidgets plays to their preferences. Phidgets clips together their pricey peripherals and the rest is all done in code using familiar modern languages and libraries. We wonder just how large this group could still be; Phidgets might have been an interesting kit years ago when the gulf between disciplines was broader but the trend these days is towards everyone knowing a little about everything. Hackaday readers probably represent that trend more than most, but let us know if that seems off.

[Ken]’s article has much more and much better detailed explanations of the experiments and the tradeoffs between the platforms.

If you enjoy watching parallel engineering, see the time-lapse video below for a split screen of the time trials.


Filed under: reviews, Software Development

Math machine learning

Whenever I observe my daughter, I find that she likes to collect things. The more, the better. Usually as much as she can carry. As she can not count, how can she distinguish, what are more things and what are less things?

My daughter with objects in both hands

read more

Giving the Arduino deques, vectors and streams with the standard template library

The Arduino IDE is extremely similar to C++, but judging from the sketches you can find on the Internet, you’d never know it. Simpler Arduino projects can make do with just toggling IO pins, reading values, and sending serial data between two points. More complex builds fall into the category of real software development, and this is where the standard Arduino IDE falls miserably short.

[Andy] saw this lack of proper libraries for more complicated pieces of software as a terrible situation and decided to do something about it. He ported the SGI Standard Template Library to bring all those fun algorithms and data structures to any AVR chip, including the Arduino.

Going over what’s included in [Andy]‘s port reads just like a syllabus for an object-oriented programming class. Stacks, queues, and lists make the cut, as do strings and vectors. Also included is just about everything in the   and headers along with a few Arduino-oriented additions like a hardware serial and liquid crystal streams.

With all these objects floating around, [Andy] says it will make an impact on Flash and SRAM usage in an AVR. Still, with all the hullabaloo over faster and larger ARM micros, it’s nice to see the classic 8-bit microcontroller becoming a bit more refined.


Filed under: arduino hacks, Software Development

3D games for the Arduino with raycasting

For all the Arduino-based video game builds we’ve seen, we’re really only left with a bunch of 2D platformers and other sprite-based games. [Reimecker] wasn’t satisfied with this level of computational complexity, so he ported the 3D game engine made famous by Duke Nukem 3D to the Arduino (German, Google translation).

[Reimecker]‘s project is based on the very popular Build Engine written by [Ken Silverman] and used in games such as Duke Nukem 3D,  Shadow Warrior,  Blood, and TekWar. The Build Engine can be used to make a first person shooter, but more on the level of Wolfenstein 3D instead of Half-Life.

The hardware [Reimecker] used is a regular ‘ol 8-bit Arduino with an attached LCD touch screen displaying 320×240 pixels of a ray cast environment. From the videos of the build (available after the break), [Reimecker] has a fairly decent game engine capable of displaying a 2.5D environment. The frame rate might not be very high, but it’s still an amazing build considering the hardware [Reimecker] is working with.


Filed under: arduino hacks, Software Development