我正在尝试制作一个简单的预处理器循环。 (我意识到这是一个可怕的想法,但是哦,好吧。)
// Preprocessor.h
#ifndef PREPROCESSOR_LOOP_ITERATION
#define MAX_LOOP_ITERATION 16 // This can be changed.
#define PREPROCESSOR_LOOP_ITERATION 0
#endif
#if (PREPROCESSOR_LOOP_ITERATION < MAX_LOOP_ITERATION)
#define PREPROCESSOR_LOOP_ITERATION (PREPROCESSOR_LOOP_ITERATION + 1) // Increment PREPROCESSOR_LOOP_ITERATION.
#include "Preprocessor.h"
#endif
问题是它看起来不像 PREPROCESSOR_LOOP_ITERATION
正在递增,所以它只是无限地包含自己。如果我将该行更改为实际整数(如 17
),预处理器会正确地跳过 #include
指令。
我做错了什么?
最佳答案
“问题”是宏被惰性求值。考虑您的宏定义:
#define PREPROCESSOR_LOOP_ITERATION (PREPROCESSOR_LOOP_ITERATION + 1)
这定义了一个名为 PREPROCESSOR_LOOP_ITERATION
的宏,它的替换列表是五个预处理标记的序列 (
, PREPROCESSOR_LOOP_ITERATION
, +
、1
和 )
。定义宏时,宏不会在替换列表中扩展。宏替换仅在您调用宏时发生。考虑一个更简单的例子:
#define A X
#define B A
B // this expands to the token X
#undef A
#define A Y
B // this expands to the token Y
还有一个额外的规则,如果在替换列表中遇到被替换的宏的名称,则不会将其视为宏,因此不会被替换(这有效地禁止了宏替换期间的递归)。因此,在您的情况下,每当您调用 PREPROCESSOR_LOOP_ITERATION
宏时,它都会被替换为
( PREPROCESSOR_LOOP_ITERATION + 1 )
然后宏替换停止,预处理继续下一个标记。
您可以通过定义一系列宏并使用连接 (##
) 运算符来使用预处理器执行有限的算术运算,但它非常乏味。您应该考虑使用 Boost.Preprocessor图书馆来帮助你。它适用于 C 和 C++ 代码。它允许有限的迭代,但它所允许的是非常有用的。最接近您的用例的功能可能是 BOOST_PP_ITERATE
。序列 (BOOST_PP_SEQ
) 处理程序等其他工具对于编写生成代码非常有帮助。
关于c++ - 递增预处理器宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5025260/