C预处理器:__ COUNTER__的自己实现

mic*_*c_e 5 c macros c-preprocessor

我目前正在使用__COUNTER__我的C库代码中的宏来生成唯一的整数标识符.它工作得很好,但我看到两个问题:

  • 它不是任何C或C++标准的一部分.
  • 也使用的独立代码__COUNTER__可能会混淆.

因此,我希望实现与__COUNTER__我自己的等价物.

我所知道的,但替代品并不需要使用:

  • __LINE__ (因为每行多个宏不会获得唯一ID)
  • BOOST_PP_COUNTER(因为我不想要boost依赖)

BOOST_PP_COUNTER证明这可以做到,即使其他答案声称这是不可能的.

本质上,我正在寻找一个头文件"mycounter.h",这样

#include "mycounter.h"

__MYCOUNTER__
__MYCOUNTER__ __MYCOUNTER__
__MYCOUNTER__
Run Code Online (Sandbox Code Playgroud)

将进行预处理gcc -E,以

(...)

0
1 2
3
Run Code Online (Sandbox Code Playgroud)

不使用内置__COUNTER__.

注:此前,这个问题被标记为重复这个,它使用交易__COUNTER__,而不是回避它.

Leu*_*nko 3

你不能__COUNTER__直接实施。预处理器纯粹是功能性的——没有状态改变。在这样的系统中,隐藏的计数器本质上是不可能的。(并不能BOOST_PP_COUNTER证明你想要的东西可以完成 - 它依赖于并且因此只能每行一个 - 也可以使用。也就是说,实现非常出色,无论如何你都应该阅读它。)#include__LINE__

您可以做的是重构您的元程序,以便可以通过纯函数将计数器应用于输入数据。例如使用良好的订单

#include <order/interpreter.h>

#define ORDER_PP_DEF_8map_count  \
ORDER_PP_FN(8fn(8L, 8rec_mc(8L, 8nil, 0)))

#define ORDER_PP_DEF_8rec_mc     \
ORDER_PP_FN(8fn(8L, 8R, 8C,      \
                8if(8is_nil(8L), \
                    8R,          \
                    8let((8H, 8seq_head(8L))  \
                         (8T, 8seq_tail(8L))  \
                         (8D, 8plus(8C, 1)),  \
                          8if(8is_seq(8H),    \
                              8rec_mc(8T, 8seq_append(8R, 8seq_take(1, 8L)), 8C),  \
                              8rec_mc(8T, 8seq_append(8R, 8seq(8C)), 8D) )))))

ORDER_PP (
  8map_count(8seq( 8seq(8(A)), 8true, 8seq(8(C)), 8true, 8true ))  //((A))(0)((C))(1)(2)
)
Run Code Online (Sandbox Code Playgroud)

(向下递归列表,将子列表元素保留在原处,并8false用递增计数器变量替换非列表元素 - 表示 - )

我假设您实际上不想简单地__COUNTER__在程序顶层删除值,因此,如果您可以将需要将值编织到其中的代码放入__COUNTER__包装器宏中,将其拆分为某种序列或列表,那么您可以提供与示例类似的纯函数列表。

当然,能够表达此类代码的元编程库的可移植性和可维护性将明显低于__COUNTER__其他任何方式。__COUNTER__受 Intel、GCC、Clang 和 MSVC 支持。(不是每个人,例如pcc没有它,但有人使用它吗?)可以说,如果您在实际代码中演示了该功能,那么它会向标准化委员会提供更有力的案例,该委员会__COUNTER__ 应该成为下一个 C 标准的一部分。