Writing Generic Code for C Compilers – Techniques and Tips

cembedded-systemsgeneric-programming

I need to write some algorithms for a PIC micro controller. AFAIK, the official tools support either assembler or a subset of C.

My goal is to write the algorithms in a generic and reusable way without losing any runtime or memory performance. And if possible, I would like to do this without increasing the development time much and compromising the readability and maintainability much either.

What I mean by generic and reusable is that I don't want to commit to types, array sizes, number of bits in a bit field etc. All these specifications, IMHO, point to C++ templates, but there's no compiler for it for my target. C macro metaprogramming is another option, but, again my opinion, that greatly reduces readability and increases development time.

I believe what I'm looking for is a decent C++ to C translator, but I'd like to hear anything else that satisfies the above requirements. Maybe a translator from another high-level language to C that produces very efficient code, maybe something else.

Please note that I have nothing against C, I just wish templates were available in it.

Best Answer

Unless you have at least 3 use-cases where the algorithms will be used with different types and sizes, you are not going to do good job of the genericity anyway. So don't bother too much.

I'd recommend writing it in plain C using custom typedefs for all types (except things that are obviously size_t, int or such) and #defines for any relevant sizes. Than you can adjust the algorithms easily by changing those definitions. You can put the definitions in one header that you can easily override for the use-cases.

You can also use the C's poor man's template system, the preprocessor. Like define a macro, that will get a type and expand to definition of the function for that type. Or define the parameters to expand, include a header/source to define the functions and undefine the parameters again. The later does not convolute diagnostics as much and is probably easier to manage.

Something like:

  • sort.h:

     void sort_##SORT_TYPE(SORT_TYPE *begin, SORT_TYPE *end);
    

    IIRC you'll need some wrapper macro to get the definition expanded appropriate number of times.

  • sort.c:

     void sort_##SORT_TYPE(SORT_TYPE *begin, SORT_TYPE *end)
     {
         // whatever
         if(SORT_LESS(i, j)) // ...
         // ..
     }
    
  • using:

     #define SORT_TYPE int
     static inline int less(int x, int y) { return x < y; }
     #define SORT_LESS less
     #include "sort.h"
     #include "sort.c" // you only do this in a .c file
     #undef SORT_TYPE
     #undef SORT_LESS