Hi!

At work, I'm currently using x-macros to allow compile-time configuration of some filtering software. It boils down to a configuration file that roughly looks like this:

CFG_START() CFG_ADD(int, FOO, /* some more stuff */) CFG_ADD(short, BAR, /* some more stuff */) CFG_ADD(float, BAZ, /* some more stuff */) CFG_END()

This file generates some variables, and a meta-data table for the running software so it can know the types (int, short, float) for the variables associated with the identifiers (FOO, BAR, BAZ).

So far, no problems, just a little bit of creative usage of the C preprocessor.

The running software has to invoke qsort. qsort needs a compare function. The meta-data table contains pointers to the compare function matching the type, simply by appending the type name to a common prefix:

/* simplified */ MetaData_t metadata = { #define CFG_ADD(TYPE,NAME,STUFF) { .compFunc = compare_ ## TYPE; / +* and some more stuff */ } #include "configfile.h" #undef CFG_ADD }

My source contains a lot of compare functions for different types that could be used in the configuration file. But not all of the functions are actually used, because not all of the types are used in the configuration file. So, the compiler warns about some unused functions (e.g. compare_double() for the example shown above).

Yes, it is harmless, but ugly. Our code should compile without warnings. Disabling the warning is not an option. I would prefer to be able to hide unused functions from the C compiler.

Something like this (and yes, I know this won't work):

#define CFG_ADD(TYPE,NAME,STUFF) \ #ifndef USING_ ## TYPE /* does not work */ \ #define USING_ ## TYPE /* does not work */ \ #endif #include "configfile.h" #undef CFG_ADD /* and later: */ #ifdef USING_int static int compare_int(const void * a, const void * b); #endif #ifdef USING_double static int compare_double(const void * a, const void * b); #endif /* further down */ #ifdef USING_int static int compare_int(const void * a, const void * b) { /* ... */ } #endif #ifdef USING_double static int compare_double(const void * a, const void * b) { /* ... */ } #endif

Any clever ideas that I missed?

Environment: GCC 4.x cross-compiling for an embedded system (so code and data size might become a problem). GCC might be updated in the future, but switching to a different compiler is very unlikely. So a GCC-only solution is acceptable.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to [OT] Abusing the C preprocessor by afoken

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.