C 预处理器:__COUNTER__ 的自己的实现 [英] C Preprocessor: Own implementation for __COUNTER__
问题描述
我目前在我的 C 库代码中使用 __COUNTER__
宏来生成唯一的整数标识符.它运行良好,但我发现两个问题:
I'm currently using the __COUNTER__
macro in my C library code to generate unique integer identifiers. It works nicely, but I see two issues:
- 它不属于任何 C 或 C++ 标准.
- 也使用
__COUNTER__
的独立代码可能会混淆.
- It's not part of any C or C++ standard.
- Independent code that also uses
__COUNTER__
might get confused.
因此,我希望自己实现一个等效于 __COUNTER__
的功能.
I thus wish to implement an equivalent to __COUNTER__
myself.
我知道但不想想使用的替代方法:
Alternatives that I'm aware of, but do not want to use:
__LINE__
(因为每行多个宏不会获得唯一的 ID)BOOST_PP_COUNTER
(因为我不想要boost
依赖)
__LINE__
(because multiple macros per line wouldn't get unique ids)BOOST_PP_COUNTER
(because I don't want aboost
dependency)
BOOST_PP_COUNTER
证明这是可以做到的,即使 other 回答声称这是不可能的.
BOOST_PP_COUNTER
proves that this can be done, even though other answers claim it is impossible.
本质上,我正在寻找一个头文件mycounter.h",这样
In essence, I'm looking for a header file "mycounter.h", such that
#include "mycounter.h"
__MYCOUNTER__
__MYCOUNTER__ __MYCOUNTER__
__MYCOUNTER__
会被gcc -E
预处理到
(...)
0
1 2
3
不使用内置 __COUNTER__
.
注意:之前,此问题被标记为与 this 重复,其中处理使用 __COUNTER__
而不是避免它.
Note: Earlier, this question was marked as a duplicate of this, which deals with using __COUNTER__
rather than avoiding it.
推荐答案
不能直接实现__COUNTER__
.预处理器纯粹是功能性的——没有状态变化.在这样的系统中,隐藏计数器本质上是不可能的.(BOOST_PP_COUNTER
确实 not 证明你想要什么可以完成 - 它依赖于 #include
,因此仅每行一个 - 可能是好好使用 __LINE__
.也就是说,它的实现很棒,无论如何你都应该阅读它.)
You can't implement __COUNTER__
directly. The preprocessor is purely functional - no state changes. A hidden counter is inherently impossible in such a system. (BOOST_PP_COUNTER
does not prove what you want can be done - it relies on #include
and is therefore one-per-line only - may as well use __LINE__
. That said, the implementation is brilliant, you should read it anyway.)
您可以做的是重构您的元程序,以便计数器可以通过纯函数应用于输入数据.例如使用好的 ol' Order:
What you can do is refactor your metaprogram so that the counter could be applied to the input data by a pure function. e.g. using good ol' Order:
#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)
)
(向下递归列表,将子列表元素留在原处,并用递增的计数器变量替换非列表元素 - 由 8false
表示)
(recurses down the list, leaving sublist elements where they are and replacing non-list elements - represented by 8false
- with an incrementing counter variable)
我假设您实际上并不想简单地在程序顶层删除 __COUNTER__
值,因此如果您可以将需要编织 __COUNTER__
值的代码放入其中在将其拆分为某种序列或列表的包装宏中,您可以将列表提供给类似于示例的纯函数.
I assume you don't actually want to simply drop __COUNTER__
values at the program toplevel, so if you can place the code into which you need to weave __COUNTER__
values inside a wrapper macro that splits it into some kind of sequence or list, you can then feed the list to a pure function similar to the example.
当然,能够表达此类代码的元编程库将显着比 __COUNTER__
的可移植性和可维护性差.__COUNTER__
被 Intel、GCC、Clang 和 MSVC 支持.(不是每个人,例如 pcc
都没有它,但有人甚至使用它吗?)可以说,如果您在实际代码中演示该功能,那么标准化委员会会更有力地证明 __COUNTER__
应该成为下一个 C 标准的一部分.
Of course a metaprogramming library capable of expressing such code is going to be significantly less portable and maintainable than __COUNTER__
anyway. __COUNTER__
is supported by Intel, GCC, Clang and MSVC. (not everyone, e.g. pcc
doesn't have it, but does anyone even use that?) Arguably if you demonstrate the feature in use in real code, it makes a stronger case to the standardisation committee that __COUNTER__
should become part of the next C standard.
这篇关于C 预处理器:__COUNTER__ 的自己的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!