7

I'm sitting on some legacy code that generates a lot of code through #defines. Now I know it's not possible to have an #ifdef inside a #define, but is an #if possible? I would like to do add some specialization for a specific type. (without making major changes like using templates instead). The following sample gives me cryptic errors so this is not the way:

#define MK_GET(type) \
  type get_ ## type (int index) \
  { \
    #if type == double \  <-- what i want to add
      specialized code... \
    #endif
    ...
  } \

MK_GET(double);
MK_GET(int);
MK_GET(string);
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Frank
  • 435
  • 1
  • 9
  • 13

4 Answers4

6

You could achieve that with templates:

template<typename T>
struct getter
{
    T operator()(int index)
    {
        // general code
    }
};

template<>
struct getter<double>
{
    T operator()(int index)
    {
        // specialized code
    }
};

#define CAT(a, b) a ## b
#define MK_GET(type) type CAT(get_, type) (int index) getter<type>()(index)
ronag
  • 49,529
  • 25
  • 126
  • 221
  • This! Generally, many larger #define's can be reduced to a template and small defines. You'll thank me when having to debug it. – peterchen Dec 08 '11 at 08:26
  • This is a good way, thanx. It never occured to me i could use smaller template snippetes without changing the whole #define structures in the program :) – Frank Dec 08 '11 at 08:28
2

The pre-processor is one pass process, so you can't place macro defines inside of macro defines. The only way to do this is via the template interface.

DipSwitch
  • 5,470
  • 2
  • 20
  • 24
0

Why you dont write it like this:

#if (type == double)
    #define MK_GET  some code
#else
    #define MK_GET  same code with changes
#endif
Gil.I
  • 895
  • 12
  • 23
  • 1
    Because then you can only have one define per module and you cannot generate code for all types in one module... – DipSwitch Dec 08 '11 at 08:20
0

#if cannot be nested inside #define. Why you want to avoid templates when that is the better choice. They are safe and "compilable" (not preprocessed).

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Yes ofcrouse. But i dont want to make too big changes to running production code for a small fix. – Frank Dec 08 '11 at 08:23
  • They actually can...you just have to run the preprocessor more than once (in fact, once for each nesting level). It's a stupid thing to do, but it can be done. See, for instance, the vik2 entry in the international obfuscated c code contest from 2004 (http://www.ioccc.org/years.html#2004) and it's associated Makefile – Daisy Sophia Hollman Jan 26 '12 at 14:03