- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
测试预处理器符号是否定义的常用方法是使用#ifdef
。但是,#ifdef
不能在宏中使用。如果宏的参数是定义的预处理器符号,我需要一种方法来检入该宏。
例如:
#define TRACE(x,y) if(IS_DEFINED(x)){ std::cout << y; }
这里,TRACE
有两个参数,第一个 x
应该是预处理器符号的名称。如果定义了这样的符号,则应打印第二个参数。我正在寻找不存在的 IS_DEFINED
函数/宏。
用法如下:
#undef BLA
TRACE(BLA,"abc") // "abc" won't be printed, as BLA is not defined
#define BLA 1
TRACE(BLA,"xyz") // "xyz" will be printed, as BLA is a defined symbol
有办法实现吗?也许一些宏观魔法?当然,这些解决方案应该适用于任何符号,而不仅仅是 BLA
或一组硬编码的符号。如果事先知道要检查的符号集,显然很容易。
最佳答案
将字符串化宏(名称)与宏的字符串化(扩展)值进行比较:
#include <iostream>
#include <cstring>
#define TRACE_STRINGIFY(item) "" #item
#define TRACE(macro, message) \
do { \
if (strcmp("" #macro, TRACE_STRINGIFY(macro))) \
std::cout << message << "\n"; \
} while (0)
""#macro
将宏名称扩展为字符串,而 TRACE_STRINGIFY(macro)
首先扩展宏,然后将结果字符串化。如果两者不同,macro
必须是预处理器宏。
对于为自身定义的宏,即 #define FOO FOO
,此方法确实失败。此类宏不会被检测为预处理器宏。
大多数编译器应该能够完全优化两个字符串文字的比较。 GNU GCC (g++) 4.8.2 甚至可以使用 -O0
(对于 C 的 gcc 也是如此——同样的方法显然也适用于 C)。
这种方法确实适用于类似函数的宏,但前提是您保留括号(如果宏采用多个参数,则保留适当数量的逗号)并且它本身没有定义(例如 #define BAR( x) BAR(x)
).
例如:
#define TEST1 TEST1
#define TEST3
#define TEST4 0
#define TEST5 1
#define TEST6 "string"
#define TEST7 ""
#define TEST8 NULL
#define TEST9 TEST3
#define TEST10 TEST2
#define TEST11(x)
#define TEST13(x,y,z) (x, y, z)
int main(void)
{
TRACE(TEST1, "TEST1 is defined");
TRACE(TEST2, "TEST2 is defined");
TRACE(TEST3, "TEST3 is defined");
TRACE(TEST4, "TEST4 is defined");
TRACE(TEST5, "TEST5 is defined");
TRACE(TEST6, "TEST6 is defined");
TRACE(TEST7, "TEST7 is defined");
TRACE(TEST8, "TEST8 is defined");
TRACE(TEST9, "TEST9 is defined");
TRACE(TEST10, "TEST10 is defined");
TRACE(TEST11, "TEST11 is defined");
TRACE(TEST12, "TEST12 is defined");
TRACE(TEST13, "TEST13 is defined");
TRACE(TEST14, "TEST14 is defined");
TRACE(TEST1(), "TEST1() is defined");
TRACE(TEST2(), "TEST2() is defined");
TRACE(TEST3(), "TEST3() is defined");
TRACE(TEST4(), "TEST4() is defined");
TRACE(TEST5(), "TEST5() is defined");
TRACE(TEST6(), "TEST6() is defined");
TRACE(TEST7(), "TEST7() is defined");
TRACE(TEST8(), "TEST8() is defined");
TRACE(TEST9(), "TEST9() is defined");
TRACE(TEST10(), "TEST10() is defined");
TRACE(TEST11(), "TEST11() is defined");
TRACE(TEST12(), "TEST12() is defined");
TRACE(TEST13(,,), "TEST13(,,) is defined");
TRACE(TEST14(,,), "TEST14(,,) is defined");
return 0;
}
哪些输出
TEST3 is defined
TEST4 is defined
TEST5 is defined
TEST6 is defined
TEST7 is defined
TEST8 is defined
TEST9 is defined
TEST10 is defined
TEST3() is defined
TEST4() is defined
TEST5() is defined
TEST6() is defined
TEST7() is defined
TEST8() is defined
TEST9() is defined
TEST10() is defined
TEST11() is defined
TEST13(,,) is defined
换句话说,TEST1
符号未被识别为已定义(因为它是为其自身定义的),TEST11
或 TEST13
也未被识别没有括号。这些是这种方法的局限性。
使用括号形式适用于所有无参数宏(TEST1
除外,即定义给它们自己的宏)和所有单参数宏。如果一个宏需要多个参数,你需要使用正确数量的逗号,否则(比如,如果你试过 TRACE(TEST13(), "...")
)你会得到一个编译 -时间错误:“宏 TEST13
需要 3 个参数,仅给定 1 个” 或类似内容。
有问题吗?
关于c - 测试预处理器符号是否在宏中定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26099745/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!