当前位置:  开发笔记 > 编程语言 > 正文

C预处理器:尽早评估宏

如何解决《C预处理器:尽早评估宏》经验,为你挑选了2个好方法。

请考虑以下设置:

#define A 5
#define B A
#undef A
#define A 3

AC

#include "a.h"
#include 

int main()
{
    printf("%d\n", B);
    return 0;
}

虽然这非常合理地打印3,有没有办法让它打印5,即在第二行啊已经替换为5的A?



1> rici..:

不,没有办法做到这一点.除非你知道所有可能的值A,并且它们总是整数,在这种情况下你可以依次费力地测试每一个:

#if A == 0
# define B 0
#elif A == 1
# define B 1
#elif A == 2
# define B 2
/*  ... and a very long etc. */
#endif

如果您的用例仅涉及整数,那么您有更多选择.例如,您可以声明Bstatic const intenum(取决于语言)而不是宏,这显然会使用宏的当前值.如果你真的真的想要宏,那么Boost预处理库就可以实现#if上面繁琐的s 序列(有一些巧妙的做法可以减少log(N)而不是N所需的预处理器语句的数量).


#define预处理器指令中没有宏替换; §6.10段中涵盖了这一事实.C标准中的7个(C++标准第16段第6段,措辞相同):

除非另有说明,否则预处理指令中的预处理标记不受宏扩展的影响.

#if#include指令的描述中,标准指定宏替换确实发生,这就是#if上面的解决方案工作的原因(以及Boost实现,它也使用计算#include).



2> Leushenko..:

是.Boost的预处理器库(一组可移植包含,而不是扩展的预处理器)包括对"可变"宏定义的支持.您可以将其定义为扩展为引用可变槽,而不是将宏定义为直接扩展为值,可以更改它,因为它可以提前将"已分配"值扩展到它.在这种情况下,你对改变价值的能力不太感兴趣,而不是事实上这种早期扩张意味着它可以A在使用B或重新定义之前的某个点上获取价值A.

#include 

#define A 5
#define B BOOST_PP_SLOT(1)

// "assign" A to B
#define BOOST_PP_VALUE A
#include BOOST_PP_ASSIGN_SLOT(1)

#undef A
#define A 3

#include "a.h"
#include 

int main()
{
    printf("%d\n", B);  // 5
    return 0;
}

支持仅限于整数.它充分利用了事实的优点#if的任何指示力扩展包含宏(所以做#line#error,虽然这些都不是为了这个目的非常有用),并使用它们来建立一个相当于整数值的插槽被分配到,存储在隐藏后端宏.这样它就可以从中"提取"一个值A,B然后即使A更改或被删除也可以引用该值本身.


`#include BOOST_PP_ASSIGN_SLOT(1)`...这病了!我们不需要混淆的C++代码竞赛,我们有所提升!
推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有