User Interfaces and Usability for Embedded Systems

Feedback to Assertiveness Training for Programmers - Murphy's Law, Apr' 2001

return to Murphy's Law


This column has a mistake in the first example in the Size Matters section. The example is:

assert (sizeof(struct myData) > SIZE);

It should read:

assert (sizeof(struct myData) <= SIZE);

My thanks to Scott Newell for pointing this out to me.


Bill Emsholl mailed me with a method for doing compile time asserts without using a single byte of ROM or RAM - something I narrowly failed to do in the column itself. His useful mail follows:

Thanks for writing a column on the use of assert(). I too, have also found that this macro is still not widely used, and is often misused.

However, I would like to offer a better compile-time assert macro than the use of a static variable as illustrated in the article. Besides the fact that many compilers recognize a zero-sized array as valid, most compilers will also produce a spurious warning on unused variables.

These problems can be solved through the use of a typedef to an array whose dimensions are positive or negative depending on the expression, as below:

/* macro to test an expression at compile time.
produces a compiler error if invalid; produces no code if valid.
The expression is in braces to allow it to be used multiple times
in the same block.
#define CASSERT(ex) { typedef char cassert_type[(ex) ? 1 : -1]; }

void foo(void) {
CASSERT(sizeof(char) >= 1);
CASSERT(sizeof(int) >= 2);

void bar(void) {
CASSERT(sizeof(char) >= 2); // compile-time error

The above macro was tested on 3 different C/C++ compilers, and a typedef doesn't even occupy a single byte of storage...

Keep up the good work,

Bill Bill Emshoff
Lockheed Martin Aeronautics

Well I thought I couldn't be the first to discover this one, and I see I'm not. I have just found a variant of this at... http://www.panelsoft.com/murphyslaw/apr01.htm

This is a definite improvement since it uses a harmless typedef instead.

However, Bill Emsholl's variant doesn't swallow the semicolon and it cannot be used outside a function (at file scope).

So here is my new variant....

#define COMPILE_TIME_ASSERT(ex) do {\
typedef char COMPILE_TIME_ASSERTION_FAILURE[(ex) ? 1 : -1];\
} while(0)

extern char COMPILE_TIME_ASSERTION_FAILURE[(ex) ? 1 : -1];

FILE_SCOPED_COMPILE_TIME_ASSERT(sizeof(char)==2); // Compiler whinges

int main(void)

      COMPILE_TIME_ASSERT(0); // Compiler whinges.

   return 0;

John Carter
Tait Electronics
New Zealand


Another vote for the healing powers of assert macros:


I just read your article on the Assert() macro. Like you I've been astounded at the number of "professional" software engineers who've never heard of it. I learnt about it from McQuire's book about a year ago, and have since liberally sprinkled assertions throught my embedded code during development. It very quickly shows up serious program flow errors, which are the bugs that usually slip through.

The article was very good.

Phil Matthews

Hi Niall,

I like the trick you give to validate the size of a structure. I'm using it to validate at compilation that the size of our global structures match the documentation. I ran into a problem with our tool vendor's C/CPP compiler. It will allocate an array of 0 bytes. The compiler doesn't give you an error until you attempt to access the zero length array!


Robert E. Lee
Firmware Engineer
GE Meter Business Department

Niall's Response:

I have to admit I have gone off this trick for a while. I (and others) have discovered that compilers are not strict enough in this area, so you can never be sure if it is going to work - regardless of what the C standard says. My compromise is to use an assert, which has a small cost in space, and the error is only reported at run-time, but at least the run-time assert is traced back to the exact cause of the failure (unlike accessing out of bounds areas, which can be hard to debug).

[PanelSoft Home | Training Courses ]