[英]C Preprocessor: Own implementation for __COUNTER__
I'm currently using the __COUNTER__
macro in my C library code to generate unique integer identifiers. 我当前在C库代码中使用
__COUNTER__
宏来生成唯一的整数标识符。 It works nicely, but I see two issues: 效果很好,但是我看到两个问题:
__COUNTER__
might get confused. __COUNTER__
独立代码可能会造成混淆。 I thus wish to implement an equivalent to __COUNTER__
myself. 因此,我希望自己实现与
__COUNTER__
等效的__COUNTER__
。
Alternatives that I'm aware of, but do not want to use: 我知道但不希望使用的替代方法:
__LINE__
(because multiple macros per line wouldn't get unique ids) __LINE__
(因为每行多个宏不会获得唯一的ID) BOOST_PP_COUNTER
(because I don't want a boost
dependency) BOOST_PP_COUNTER
(因为我不想boost
依赖) BOOST_PP_COUNTER
proves that this can be done, even though other answers claim it is impossible. BOOST_PP_COUNTER
证明可以做到这一点,即使其他答案认为这是不可能的。
In essence, I'm looking for a header file "mycounter.h", such that 本质上,我正在寻找头文件“ mycounter.h”,这样
#include "mycounter.h"
__MYCOUNTER__
__MYCOUNTER__ __MYCOUNTER__
__MYCOUNTER__
will be preprocessed by gcc -E
to 将由
gcc -E
预处理为
(...)
0
1 2
3
without using the built-in __COUNTER__
. 而不使用内置的
__COUNTER__
。
Note: Earlier, this question was marked as a duplicate of this , which deals with using __COUNTER__
rather than avoiding it. 注意:之前,此问题被标记为this的重复,它使用
__COUNTER__
而不是避免使用。
You can't implement __COUNTER__
directly. 您不能直接实现
__COUNTER__
。 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.) (
BOOST_PP_COUNTER
不能证明您要完成的工作-它依赖于#include
,因此仅一行执行-最好使用__LINE__
。也就是说,实现非常出色,无论如何都应该阅读它。)
What you can do is refactor your metaprogram so that the counter could be applied to the input data by a pure function. 您可以做的是重构您的元程序,以便可以通过纯函数将计数器应用于输入数据。 eg 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)
)
(recurses down the list, leaving sublist elements where they are and replacing non-list elements - represented by 8false
- with an incrementing counter variable) (沿列表递归,将子列表元素留在原处,并用递增计数器变量替换非列表元素(由
8false
表示))
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__
值的代码放入包装宏中,该宏会将其拆分为某种序列或列表,则可以然后将列表提供给与示例类似的纯函数。
Of course a metaprogramming library capable of expressing such code is going to be significantly less portable and maintainable than __COUNTER__
anyway. 当然,与
__COUNTER__
相比,能够表达这种代码的元编程库的可移植性和可维护性将大大降低。 __COUNTER__
is supported by Intel, GCC, Clang and MSVC. __COUNTER__
受Intel,GCC,Clang和MSVC支持。 (not everyone, eg 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. (不是所有人,例如
pcc
都没有,但是有人甚至使用它吗?)可以说,如果您在实际代码中演示了正在使用的功能,则对于标准化委员会来说, __COUNTER__
应该成为下一个C的一部分更有力。标准。
You are confusing two different things: 您在混淆两件事:
1 - the preprocessor which handles #define
and #include
like stuff. 1-处理
#define
和#include
类的预处理器。 It does only works as the text (meaning character sequences) level and has very few computing capabilities. 它仅在文本(含义是字符序列)级别上起作用,并且具有很少的计算能力。 It is so limited that it cannot implement
__COUNTER__
. 它是如此有限,以致于无法实现
__COUNTER__
。 The preprocessor work consist only in macro expansion and file replacement. 预处理程序仅包括宏扩展和文件替换。 The crucial point it that it occur before the compilation even start.
至关重要的一点是,它甚至在编译开始之前就已发生。
2 - the C++ language and in particular the template (meta)programming language which can be used to compute stuff during the compilation phase. 2-C ++语言,尤其是模板(元)编程语言,可用于在编译阶段计算内容。 It is indeed turing complete but as I already said compilation start after preprocessing.
它确实已经完成,但是正如我已经说过的,编译是在预处理之后开始的。
So what you are asking is not doable in standard C or C++. 因此,您要问的是在标准C或C ++中不可行。 To solve this problem
boost
implement its own preprocessor which is not standard compliant and has much more computing capabilities. 为了解决这个问题,
boost
实现了自己的不符合标准且具有更多计算能力的预处理器。 In particular it is possible to use build an analogue to __counter__
with it. 特别地,可以使用
__counter__
建立__counter__
的类似物。
我的这个小标头包含一个自己的C预处理程序计数器实现(它使用略有不同的语法)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.