Why does sequence iteration work in C macro?

When writing a C macro, there is a trick called sequence iteration. It looks like this:

#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define FUNCTION(name) void name();
#define FUNCTION_TABLE(seq) CAT(FUNCTION_TABLE_1 seq, _END)
#define FUNCTION_TABLE_1(x) FUNCTION(x) FUNCTION_TABLE_2
#define FUNCTION_TABLE_2(x) FUNCTION(x) FUNCTION_TABLE_1
#define FUNCTION_TABLE_1_END
#define FUNCTION_TABLE_2_END

FUNCTION_TABLE((x) (y) (z) (e))

The sequence, that is, the argument FUCTION_TABLE, will be processed one after another. However, as far as I know, the token will not expand twice in the same area. Because it is "painted blue." When FUNCTION_TABLE_2 expands, the macro FUNCTION_TABLE_1 is already written. Why is it still expanded?

+4
source share
2 answers

The idea is that inside the macro exchange, all parameter expansion will start from the same BLUE-SET.

FUNCTION_TABLE(seq) FUNCTION_TABLE_1 seq BLUE-SET = {seq}. FUNCTION_TABLE_1 BLUE-SET x, , FUNCTION_TABLE, BLUE-SET={seq}.

, FUNCTION_TABLE_1(x) INSIDE BLUE-SET={seq,x}, FUNCTION_TABLE_1 , FUNCTION_TABLE, FUNCTION_TABLE_2(y) INSIDE FUNCTION_TABLE_2 BLUE-SET = {seq, x} ..

+1

:

  • , # ##
  • , , , # ##,
  • # ## ( )
  • 1, 1-3 .

( , !). , :

  • FUNCTION_TABLE((x) (y) (z) (e)) CAT(FUNCTION_TABLE_1 (x) (y) (z) (e), _END)
  • CAT(X, _END) PRIMITIVE_CAT(expand(X), _END). expand(X) :
    • FUNCTION_TABLE_1 (x) (y) (z) (e) FUNCTION(x) FUNCTION_TABLE_2 (y) (z) (e):
      • FUNCTION(x) void x();
      • FUNCTION_TABLE_2 (y) (z) (e) FUNCTION(y) FUNCTION_TABLE_1 (z) (e)
      • FUNCTION(y) void y();
      • FUNCTION_TABLE_1 (z) (e) FUNCTION(z) FUNCTION_TABLE_2(e)
        • FUNCTION(z) void z();
        • FUNCTION_TABLE_2(e) FUNCTION(e) FUNCTION_TABLE_1
        • FUNCTION(e) void e();
        • : void e(); FUNCTION_TABLE_1
        • : void z(); void e(); FUNCTION_TABLE_1
      • : void y(); void z(); void e(); FUNCTION_TABLE_1
      • : void x(); void y(); void z(); void e(); FUNCTION_TABLE_1
  • , X, , : PRIMITIVE_CAT(void x(); void y(); void z(); void e(); FUNCTION_TABLE_1, _END)
  • void x(); void y(); void z(); void e(); FUNCTION_TABLE_1_END
  • void x(); void y(); void z(); void e();
+2

Source: https://habr.com/ru/post/1677221/


All Articles