tags:

views:

148

answers:

3

I've found some weird C++ preprocessor clauses, like:

#define COMPILER_FLOAT_ENTRIES_DO(template)

and

#define COMPILER_FLOAT_ENTRIES_DO(template) \
  template(jvm_fadd)  \
  template(jvm_fsub)  \
  template(jvm_f2d)  

What does passing "template" reserved word to a #define, and calling template(something) mean? I couldn't find anything at Google; probably because "#define" and "template" are really common words.

The entire code is at https://phoneme.dev.java.net/source/browse/phoneme/components/cldc/trunk/src/vm/share/ROM/ROMWriter.hpp?rev=19839&view=markup.

+8  A: 

The word "template" is a coincidence here. The preprocessor isn't sensitive to reserved words in this way, as it largely just does text operations.

That is a standard macro that takes a function name as its argument and calls that function three times with those arguments. The first version of it with nothing after looks like a debug version or some other version designed to make it a no-op in some context.

quixoto
+5  A: 
#define COMPILER_FLOAT_ENTRIES_DO(template)

so 'COMPILER_FLOAT_ENTRIES_DO(x)' gets replaced with with ''. In other words, it removes that macro from the code.

#define COMPILER_FLOAT_ENTRIES_DO(template) \
  template(jvm_fadd)  \
  template(jvm_fsub)  \
  template(jvm_f2d) 

so COMPILER_FLOAT_ENTRIES_DO(x) gets replaced with x(jvm_fadd) x(jvm_fsub) x(jvm_f2d).

If all else fails, you can see what is happening with macros by using 'g++ -E -o foo.cpp' to leave the output of macro preprocessing in 'foo.cpp'. Of course you'll need all the other compilation flags passed in by command line as well (especially -D and -I flags).

ldav1s
+3  A: 

You often find this type of coding in Data-Driven Programming design patterns.

This is handy when you want to include several times the same file (the Data) but where macros are substituted with different code or other data.

Let's assume some attributes and there respective types:

/// @file data.h
my_attribute(color, int)
my_attribute(volume, float)

The coding part can use data without even needing to know the quantity. As an example, let's print some information.

/// @file main.c
void help() 
{
  #define my_attibute(name,type) cout << #name << ": " << #type << endl;
  cout << "available attributes:" << endl;
  #include "data.h"
  #undef my_attribute
}

(note the #name is used to get the text string "color" instead of a value color)

This way your code is independent from data.

Edit: fix typo and english sentence according to @RBerteig

levif
From my experience, I'd say "often" rather than "usually". It is an essentially indispensable part of the technique you demonstrate. But it is hardly the only use for macros with parameters, and the OP's case is more likely to be some kind of optimization for a specific hardware architecture where the operation is unneeded in one architecture, and best implemented by a source text that looks like three function calls (but is likely three `asm`-ish statements) in some other architecture.
RBerteig