Live data from Hacker News

Dangerous Embedded C Coding Standard Rules (2011)

embeddedgurus.com

1–10 of 51 posts

Re: Dangerous Embedded C Coding Standard Rules (2011)

#2
Completely agree with no. 5. After a year with C I realized that macros are only to be used as control structures for headers and ifdefs to enable compatibility.

If you need macros to hack C to enable some functionality not inherent to the language, you should change the approach or switch to a different language.

Also macros are usually used to "speed up" the code. You should never optimize before finding the real bottleneck in your code. And thus always use functions instead of macros.

Re: Dangerous Embedded C Coding Standard Rules (2011)

#4
Even better rule: Know the limitations of your target processor and compiler and code accordingly.

Example 1: Some (bad) compilers just ignore the const keyword (and therefore treat consts like normal variables). Use #defines with these compilers (or get a better compiler).

Example 2: Some (older, smaller) processors don't have an integer division instruction. Avoid division at all costs on these processors unless you are not worried about space or execution speed.

Re: Dangerous Embedded C Coding Standard Rules (2011)

#5

Even better rule: Know the limitations of your target processor and compiler and code accordingly. Example 1: Some (bad) compilers just ignore the const keyword (and therefore treat consts like normal variables). Use #defines with these compilers (or get a better compiler). Example 2: Some (older, smaller) processors don't have an integer division instruction. Avoid division at all costs on these processors unless yo…

> Example 2: Some (older, smaller) processors don't have an integer division instruction. Avoid division at all costs on these processors unless you are not worried about space or execution speed.

Ok, so steer clear of division on ARM CPUs.

Re: Dangerous Embedded C Coding Standard Rules (2011)

#6
post #2

Completely agree with no. 5. After a year with C I realized that macros are only to be used as control structures for headers and ifdefs to enable compatibility. If you need macros to hack C to enable some functionality not inherent to the language, you should change the approach or switch to a different language. Also macros are usually used to "speed up" the code. You should never optimize before finding the real b…

Macros enable you to replace things at compile time.

The C preprocessor is a powerful and awesome thing by itself and I miss it when it's not available in other languages. It enables you to do things like pass line and file numbers automatically. For instance -

    #define log_message(format...) _log_message(__FILE__, __LINE__, format)
    void _log_message(char* filename, int line, char* format, ...);
And there's nothing inherently wrong with #define for frequently used magic numbers. They have the advantage of being pre-processed out rather than being separate variables at compile time.

Macros are also useful to simplify little repeated chunks of code that don't really need their own function.

I've not often seen macros used to try to speed up code.

--edit-- I don't know how long you've kept up with your C, but what you've realised after a year with the language doesn't seem as obvious to me after 15.

Re: Dangerous Embedded C Coding Standard Rules (2011)

#7

Even better rule: Know the limitations of your target processor and compiler and code accordingly. Example 1: Some (bad) compilers just ignore the const keyword (and therefore treat consts like normal variables). Use #defines with these compilers (or get a better compiler). Example 2: Some (older, smaller) processors don't have an integer division instruction. Avoid division at all costs on these processors unless yo…

Some (older, smaller) processors don't have an integer division instruction. Avoid division at all costs on these processors unless you are not worried about space or execution speed.

...unless you know your compiler is capable of converting the division into cheaper operations via strength reduction, per your well-considered rule.

Re: Dangerous Embedded C Coding Standard Rules (2011)

#8
Regarding division and shifts, one thing worth noting is that you can now (with C11) bust out static assertions to make sure no one changes the count and the shift incompatibly. It's still probably not worth doing unless there's a good reason to make sure that particular operation is a shift rather than a multiply.

Re: Dangerous Embedded C Coding Standard Rules (2011)

#9
post #7

Even better rule: Know the limitations of your target processor and compiler and code accordingly. Example 1: Some (bad) compilers just ignore the const keyword (and therefore treat consts like normal variables). Use #defines with these compilers (or get a better compiler). Example 2: Some (older, smaller) processors don't have an integer division instruction. Avoid division at all costs on these processors unless yo…

Some (older, smaller) processors don't have an integer division instruction. Avoid division at all costs on these processors unless you are not worried about space or execution speed. ...unless you know your compiler is capable of converting the division into cheaper operations via strength reduction, per your well-considered rule.

… which will (normally) only happen if the dividend is unsigned.

Another reason to prefer unsigned ints is that the C standards make signed overflow undefined. This is becoming increasingly important as code for embedded systems is built using ‘big’ optimizing compilers, rather than the simple ‘portable assemblers’ assumed by the old old rules of thumb like manually converting divides to shifts.

  “If you lie to the compiler, it will get its revenge.” — Henry Spencer

Re: Dangerous Embedded C Coding Standard Rules (2011)

#10
Another reason to pay attention to #2: Most CPUs perform simple arithmetic operations fastest on their native word size. On a 32-bit machine, addition and subtraction on 8-bit variables is probably slower than on 32-bit variables. (Often the hardware will transparently cast to 32 bits, perform the operation, then cast back to 8 bits.)

I'm not an authority on this topic, so I don't want you to take away the message "always use the machine word size". What I do want you to take away is that there are many cases where an "obvious" optimization is counterproductive in practice. Always start with simple, working code, and never optimize without benchmarking.

Post reply on HN