C++:类复杂函数的宏定义

C++: complex function-like macro definition

在阅读 node.js 源代码时,我遇到了一个我无法理解的宏。

// Strings are per-isolate primitives but Environment proxies them
// for the sake of convenience.
#define PER_ISOLATE_STRING_PROPERTIES(V)                            \
V(address_string, "address")                                        \
V(args_string, "args")                                              \
V(argv_string, "argv")                                              \
V(async, "async")                                                   \
V(async_queue_string, "_asyncQueue")                                \
V(atime_string, "atime")                                            \
...

*我假设变量(例如 address_string)是在包含的头文件中定义的。

这样持续了一段时间。我进一步查看代码以了解如何使用它。

#define V(PropertyName, StringValue)                                \
inline v8::Local<v8::String> PropertyName() const;
PER_ISOLATE_STRING_PROPERTIES(V)
#undef V

据我了解,PER_ISOLATE_STRING_PROPERTIES(V) 是一个类函数宏,它将另一个类函数宏 V 作为参数。我没有得到以下信息:

1- PER_ISOLATE_STRING_PROPERTIES(V) 被赋予了多个定义,我不明白这些在代码中是如何使用的(例如,当 PER_ISOLATE_STRING_PROPERTIES(V) 在代码中被预处理器,它怎么知道用 V 的哪个定义替换它?)
2- 我不明白 V 函数是如何使用的。

让我们 运行 仅处理以下代码:

// Strings are per-isolate primitives but Environment proxies them
// for the sake of convenience.
#define PER_ISOLATE_STRING_PROPERTIES(V)  \
  V(address_string, "address")            \
  V(args_string, "args")                  \
  V(argv_string, "argv")                  \
  V(async, "async")                       \

  #define V(PropertyName, StringValue)     \
  inline v8::Local<v8::String> PropertyName() const;
  PER_ISOLATE_STRING_PROPERTIES(V)
#undef V  

gcc -E code.cpp

这会打印出:

inline v8::Local<v8::String> address_string() const; inline v8::Local<v8::String> args_string() const; inline v8::Local<v8::String> argv_string() const; inline v8::Local<v8::String> async() const;  

C++ 是一种不区分空格的语言,所以它本质上是这样的:

inline v8::Local<v8::String> address_string() const; 
inline v8::Local<v8::String> args_string() const; 
inline v8::Local<v8::String> argv_string() const; 
inline v8::Local<v8::String> async() const; 

此技术称为 X Macros

就我个人而言,我不认为列出所有不能轻易放入 for 循环的代码有什么坏处,但是您可以看到如何使用此技术来避免指定其余代码函数签名一次又一次。宏不服从范围,我更愿意进行搜索和替换以进行更改,然后再使用宏。您就此提出了一个问题,这一事实证明它也妨碍了可读性。

tldr; 处理器用于生成代码。