Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusing macro definition in C++

Tags:

c++

macros

Recently,I am reading some code from B-Human and I ecountered this confusing snippet:

void enumInit(char* enums, const char** names, int numOfEnums);

#define ENUM(Enum, ...) \
  enum Enum : unsigned char {__VA_ARGS__, numOf##Enum##s}; \
  inline static const char* getName(Enum e) \
  { \
    static char enums[] = #__VA_ARGS__; \
    static const char* names[numOf##Enum##s]; \
    static bool init = true; \
    if(init) \
    { \
      enumInit(enums, names, numOf##Enum##s); \
      init = false; \
    } \
    return e >= numOf##Enum##s ? 0 : names[e]; \
  }

I cannot understand how this macro works, how could it be a function definition in a macro definition? It is a single cpp header file with #pragma once.

like image 476
zqzhao5 Avatar asked Oct 31 '22 20:10

zqzhao5


1 Answers

void enumInit(char* enums, const char** names, int numOfEnums);

Isn't defined anywhere in the code you posted, so strictly speaking I don't know what it does.

#define ENUM(Enum, ...) \
enum Enum : unsigned char {__VA_ARGS__, numOf##Enum##s}; \

This defines an enum with the values passed to the macro as "..." (google "variadic macro") as values, and an additional entry whose value is the number of elements in that macro and whose name is the concatenation of "numOf", the value of Enum (passed as a parameter) and "s". This last value is the entry with both value and position n if the enum contains n other values (starting at 0).

inline static const char* getName(Enum e) \
{ \
  static char enums[] = #__VA_ARGS__; \
  static const char* names[numOf##Enum##s]; \
  static bool init = true; \
  if(init) \
  { \
    enumInit(enums, names, numOf##Enum##s); \
    init = false; \
  } \
  return e >= numOf##Enum##s ? 0 : names[e]; \
}

This defines an inline function whereever your macro is called. It defines a static array containing the stringified value of the of the enum entries (enums[]), and their names (names[...]). On the first fall, enumInit(...) is called. Likely, this function fills the names array with the names of the respective enum values. For this, the string stored inside enums[] is used. To know how exactly that works, I would need to know the definition of enumInit.

edit: To more clearly answer the how could it be a function defination in a macro defination? part of your question: The macro itself is just pasted wherever it is used. The function definition is inserted whereever it is called, so that one function is generated per macro call.

like image 146
anderas Avatar answered Nov 15 '22 04:11

anderas