3

I'm attempting to define a macro that allows me to pass in 2 numbers as well as an operator. I want the macro to carry out the specified operation on the two numbers and return the result.

My definition is:

#define GENERAL_OP(x,y,op) ((x) op (y))

which works fine when I call

int result = GENERAL_OP(1, 2, -);

but as soon as I try to pass it a character (which is what I actually need to do in my generalized function that calls the macro) as in the following example:

void Evaluate(char op)...

int result = GENERAL_OP(1, 2, op);
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
John K
  • 31
  • 1
  • 1
    You could map the operators out to `std::plus` and the like. – chris Oct 25 '12 at 15:04
  • The error is the preprocessor expansion of a runtime variable. You're code effectively becomes `(1) op (2)`. *exactly*. chris' idea of mapping char-ops to std::functions is a very elegant solution, btw, and should be considered. – WhozCraig Oct 25 '12 at 15:10
  • Unfortunately I'm in C not C++ so that's not an option. I must have tagged it with C++ by accident. – John K Oct 25 '12 at 15:14

3 Answers3

9
void Evaluate(char op)...

int result = GENERAL_OP(1, 2, op);

Macro replacement is done before compile time, but the argument of Evaluate is only available at runtime, so the macro expansion leads to

int result = ((1) op (2));

there, and op is not a token that can appear there (probably an undeclared identifier).

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • Ohhh okay, that makes sense actually. Is there any alternative that would achieve what I'm trying or is this just something that requires a function with different switch cases for each possible operation? – John K Oct 25 '12 at 15:11
  • 1
    C or C++? And it depends on how many operations you want to support. For only the four arithmetic operations, I'd say a `switch` is the best option. If you have substantially more, a map `symbol -> operation` would be a good candidate, as chris suggested. – Daniel Fischer Oct 25 '12 at 15:14
0

Preprocessor operates at compile-time, you can't use the value of op inside your macro.

md5
  • 23,373
  • 3
  • 44
  • 93
0

I see what you're going for... it's sort of like trying to unstringify. I'm pretty sure it can't work the way you want it to. Your best bet would be to do something like:

void Evaluate(char op, int x, int y)
{
    int result;
    if(op == '-')
      GENERAL_OP(x, y, -);
    ...

But that doesn't make it very "general"...

Community
  • 1
  • 1
Mike
  • 47,263
  • 29
  • 113
  • 177