Sure, but I suck at explaining, however I'll try. So as you've noticed, you can't have two macros with the same name. But wait, they are different! But that doesn't matter, as the name is only the first part until first invalid character. You can read more about that
here, under "definitions" and "macros". So, we do a little trick. We are gona exploit tag system and macro parser rules - the ":" character. It's both macro name-ending character, as it is tag operator. As for tags,
read up about weak tags. Weak tags don't trigger tag mismatch errors. I've chosen "m@X" as a pattern for our tags. Why? I think I saw it in some YSI library, and also it minimizes chance of name collisions later on. Now all the pieces together
pawn Код:
#define MACRO1 m@1:m@2:@MACRO1 // Create our chain. Macro name: "MACRO1"
#define m@1:m@2:@MACRO1<%0>[%1] %0[%1] // Macro name "m@1"
#define m@2:@MACRO1<%0> %0 // Macro name "m@2"
All that's left is our m@1 tag as you've noticed. It can cause errors, if it does, you can chain tags and only outermost will be considered:
pawn Код:
new Float:bar = MACRO1<foo>; //Tag mismatch
new Float:bar = Float:MACRO1<foo>; //All good
That's why you can nest even deeper as only outermost tag counts:
pawn Код:
#include <a_samp>
#define MACRO1 m@1:m@2:m@3:@MACRO1
#define m@3:@MACRO1$%0$ (%0 + %0)
#define m@2:m@3:@MACRO1<%0> %0
#define m@1:m@2:m@3:@MACRO1<%0>[%1] %0[%1]
main() {
new Foo[32] = { -5, ... };
new bar = MACRO1<Foo>[1];
new Float:foobar = Float:MACRO1<5>;
new fizzbar = MACRO1$15$;
printf("%d %f %d", bar, foobar, fizzbar);
}
I'm not 100% certain all I said is true and/or relevant, so anyone - feel free to correct me.