views:

171

answers:

8

I know that I am trying to shoot myself in the leg ;) However, it will allow me to make the rest (big amount) of code smaller and more readable.

Is there any tricky way to create preprocessor macro inside of another preprocessor macro?

Here is the example, what I am looking for. My real scenario is more complex

// That's what I want to do and surely C++ doesn't like it.
#define MACROCREATER(B) #define MACRO##B B+B

void foo()
{
 MACROCREATOR(5) // This should create new macro (#define MACRO5 5+5)

 int a = MACRO5; // this will use new macro
}
+4  A: 

Take a look at X-Macros.

abyx
+1 Learning something new each day :)
Vitor Py
+5  A: 

No. Even if a macro expands into something that looks like a preprocessing directive, the expansion is not evaluated as a preprocessing directive.

James McNellis
+1  A: 

No. The pre-processor is single-pass. It doesn't re-evaluate the macro expansions.

What would this buy you, anyway? You can accomplish the same thing as your example by simply "inlining" the second macro into the first. eg:

#define MACRO(B) B+B

void foo()
{
  int a = MACRO(5);
}
Laurence Gonsalves
A: 

Do you really need macros? C++ can come to help, you could for example create template functions.

code-gijoe
There are many things that can be done with macros but cannot be done with templates or any other language facility.
James McNellis
@James McNellis: that kind of statement is just begging for examples...
Evan Teran
@Evan: Sure. Last month I implemented an infix expression evaluator for use with C++ integral constant expressions (as part of a preprocessor implementation I am building). I implemented an 'Operand' type to maintain signedness during the computations. Each binary operator overload would have been ten lines of code. Using two macros (one for unary, one for binary operators), I implemented all 22 operators in 32 lines of code. Two macros saved me some 200 lines of code or so and greatly cut back on what would otherwise have been boilerplate.
James McNellis
+2  A: 

The C++ Standard says (16.3.4.3):

The resulting completely macro-replaced preprocessing token sequence [... of the macro expansion...] is not processed as a preprocessing directive even if it resembles one...

So no, there is no 'official' way of achieving what you want with macros.

hkaiser
+1 for talking in standards language :-)
Kedar
A: 

As noted, one can #include a particular file more than once with different macro definitions active. This can make it practical to achieve some effects that could not be practically achieved via any other means.

As a simple example, on many embedded systems pointer indirection is very expensive compared to direct variable access. Code which uses a lot of pointer indirection may very well be twice as large and slow as code which simply uses variables. Consequently, if a particular routine is used with two sets of variables, in a scenario where one would usually pass in a pointer to a structure and then use the arrow operator, it may be far more efficient to simple put the routine in its own file (I normally use extension .i) which is #included once without macro _PASS2 defined, and a second time with. That file can then #ifdef _PASS2/#else to define macros for all the variables that should be different on the two passes. Even though the code gets generated twice, on some micros that will take less space than using the arrow operator with passed-in pointers.

supercat
A: 

Take a look at m4. It is similar to cpp, but recursive and much more powerful. I've used m4 to create a structured language for assemblers, e.g.

  cmp r0, #0
  if(eq)
    mov r1, #0
  else
    add r1, #1
  end

The "if", "else", and "end" are calls to m4 macros I wrote that generate jumps and labels, the rest is native assembly. In order to nest these if/else/end constructs, you need to do defines within a macro.

Jonathan Engdahl
A: 
Jon Purdy