0

Let's say I have already defined 9 macros from ABC_1 to ABC_9

If there is another macro XYZ(num) whose objective is to call one of the ABC_{i} based on the value of num, what is a good way to do this? i.e. XYZ(num) should call/return ABC_num.

2
  • 1
    is num a literal or a variable? Commented Oct 22, 2014 at 22:42
  • @FatalError It's a variable. Commented Oct 22, 2014 at 23:01

2 Answers 2

4

This is what the concatenation operator ## is for:

#define XYZ(num) ABC_ ## num

Arguments to macros that use concatenation (and are used with the operator) are evaluated differently, however (they aren't evaluated before being used with ##, to allow name-pasting, only in the rescan pass), so if the number is stored in a second macro (or the result of any kind of expansion, rather than a plain literal) you'll need another layer of evaluation:

#define XYZ(num) XYZ_(num)
#define XYZ_(num) ABC_ ## num

In the comments you say that num should be a variable, not a constant. The preprocessor builds compile-time expressions, not dynamic ones, so a macro isn't really going to be very useful here.

If you really wanted XYZ to have a macro definition, you could use something like this:

#define XYZ(num) ((int[]){ \
    0, ABC_1, ABC_2, ABC_3, ABC_4, ABC_5, ABC_6, ABC_7, ABC_8, ABC_9 \
}[num])

Assuming ABC_{i} are defined as int values (at any rate they must all be the same type - this applies to any method of dynamically selecting one of them), this selects one with a dynamic num by building a temporary array and selecting from it.

This has no obvious advantages over a completely non-macro solution, though. (Even if you wanted to use macro metaprogramming to generate the list of names, you could still do that in a function or array definition.)

Sign up to request clarification or add additional context in comments.

Comments

2

Yes, that's possible, using concatenation. For example:

#define FOO(x, y) BAR ##x(y)

#define BAR1(y) "hello " #y
#define BAR2(y) int y()
#define BAR3(y) return y

FOO(2, main)
{
    puts(FOO(1, world));
    FOO(3, 0);
}

This becomes:

int main()
{
    puts("hello " "world");
    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.