Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C预处理器:计数器的自身实现___C_Macros_C Preprocessor - Fatal编程技术网

C预处理器:计数器的自身实现__

C预处理器:计数器的自身实现__,c,macros,c-preprocessor,C,Macros,C Preprocessor,我目前正在使用C库代码中的\uuu计数器\uuu宏来生成唯一的整数标识符。它工作得很好,但我看到两个问题: 它不是任何C或C++标准的一部分。 同时使用\uuuu计数器的独立代码可能会混淆 因此,我希望自己实现一个与\uuuu计数器等效的计数器 我知道但不想使用的备选方案: \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(因为每行多个宏不会获得唯一的ID BOOST\u PP\u计数器(因为我不想要BOOST依赖

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

    它不是任何C或C++标准的一部分。
  • 同时使用
    \uuuu计数器的独立代码可能会混淆
因此,我希望自己实现一个与
\uuuu计数器
等效的计数器

我知道但不想使用的备选方案:

  • \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    (因为每行多个宏不会获得唯一的ID
  • BOOST\u PP\u计数器
    (因为我不想要
    BOOST
    依赖项)
BOOST\u PP\u计数器
证明了这是可以做到的,尽管答案声称这是不可能的

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

#include "mycounter.h"

__MYCOUNTER__
__MYCOUNTER__ __MYCOUNTER__
__MYCOUNTER__
将由
gcc-E
预处理到

(...)

0
1 2
3
不使用内置的计数器


注意:前面,这个问题被标记为的副本,它涉及使用
\uuuu计数器\uuuuu>而不是避免它。

您混淆了两件不同的事情:

1-处理
#定义
#包含类似内容的预处理器。它只在文本(意味着字符序列)级别工作,并且具有很少的计算能力。它非常有限,无法实现
\uuuu计数器\uuu
。预处理器的工作仅包括宏扩展和文件替换。关键的一点是它发生在编译开始之前

2——C++语言,特别是模板(元)编程语言,它可以用于编译阶段的计算。它确实是图灵完成的,但正如我已经说过的,编译是在预处理之后开始的


<> P>所以你所要求的是标准C或C++中不可行的。为了解决这个问题,boost实现了它自己的预处理器,它不符合标准,并且具有更多的计算能力。特别是,可以使用它构建一个模拟的
\uuuu计数器

您不能直接实现
\uuuu计数器
。预处理器完全是功能性的,没有状态变化。在这样一个系统中,隐藏计数器本质上是不可能的。(
BOOST\u PP\u COUNTER
并不能证明您想要做什么-它依赖于
#include
,因此每行只有一个计数器-也可以使用
(line)
。也就是说,实现非常出色,您无论如何都应该阅读它。)

您可以做的是重构元程序,以便计数器可以通过纯函数应用于输入数据。e、 g.使用良好的ol':

#包括
#定义订单数量\
订单号(8fn(8L,8rec_mc(8L,8nil,0)))
#定义订单\u PP\u DEF\u 8rec\u mc\
订单(8fn)(8L,8R,8C,\
8if(8is_nil(8L)\
8R\
8let((8H,8seq_头(8L))\
(8T,8seq_尾部(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)())(8T,8seq(8C))
订单号(
8映射计数(8序列(8(A)),8真,8序列(8(C)),8真,8真))/(A))(0)(C))(1)(2)
)
(沿列表向下递归,保留子列表元素,并用递增的计数器变量替换非列表元素(由
8false
表示)

我假设您实际上不想简单地将
\uuuuu COUNTER\uuuu
值放在程序顶层,因此如果您可以将需要编织
\uuu COUNTER\uuuu
值的代码放在包装器宏中,该宏将其拆分为某种序列或列表,那么您可以将该列表提供给一个类似于示例的纯函数


当然,与
\uuu COUNTER\uu
相比,能够表达此类代码的元编程库的可移植性和可维护性要低得多<代码>\uuuu计数器
受Intel、GCC、Clang和MSVC支持。(不是每个人都有,例如,
pcc
没有,但有人使用过吗?)可以说,如果你在实际代码中演示了正在使用的功能,它向标准化委员会提出了一个更有力的理由,即
\uuuu COUNTER\uuuu
应该成为下一个C标准的一部分。

包含了一个C预处理器计数器的实现(它使用了稍微不同的语法)。

我完全了解CPP和模板元编程之间的区别。为了消除混淆,我重新命名了这个问题。正如我在问题中提到的,这里讨论的:,CPP是图灵完全的,所以它肯定能够做到这一点。Boost甚至实现了它(使用标准CPP)很抱歉,但是你的问题是太模糊了。你想生成什么?不同的字符串?不同的变量?我解释说你不能生成宏。谢谢,我已经更新了这个问题,希望现在能更清楚。注意C和C++预处理器可以在常数i上执行算术。nteger表达式和条件指令。说预处理器工作只包括宏扩展和文件包含是不准确的。@mic_e我想你错过了关于“请注意,需要一个外部构建脚本将预处理器的输出反馈到其输入中,因此预处理器本身并不是图灵完整的。”听起来Boost做了类似的事情,所以您的选项是(1)使用Boost,或者(2)自己重新实现。在某些情况下,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
可能是
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#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)
)