有没有一种方法可以检查宏的非数字值?

8
假设我有:
#define Name Joe

有没有一种方法可以区分宏的不同值。以下内容不起作用,但您可以理解这个想法。
#if   Name==Joe
// some code
#elif Name==Ben
// some alternative code
#endif

我想使用这个工具从同一源代码生成各种对象文件。源代码只有微小的差异,因此可以轻松地进行宏控制。该宏将通过-DName=Joe编译器标志传递。请注意,Name将是一个实际的符号名称,因此我们不能使用基于#define Joe 1等的技巧。


强制编辑请注意,这个类似的问题实际上涉及到字符串值宏。此外,那里的答案并没有帮助。被接受的答案避免了这个问题(但没有解决它),另一个答案在宏中使用strcmp,这依赖于一个扩展等等。


3
你可能不想要那个(XY问题)。 - user2249683
5
为什么不直接用#define Joe来定义名称,而不是为名称赋值呢?这样你可以使用#if defined(Joe)来检查Joe是否存在。 - NathanOliver
2
数字:没问题。名称:不太行。 - user3386109
2
可能是重复的问题 如何在C条件预处理器指令中比较字符串 (尽管该问题仅涉及C语言) - PC Luddite
2
@PCLuddite -- 这绝不是重复的问题;如果你处理字符串,这种问题会更加棘手,但在这种情况下并不太困难。 - Charles Ofria
显示剩余4条评论
2个回答

12

是的,这是可能的,但并不完美。

这里有一个例子:更改名称,它会打印正确的内容。你只需要提前定义每个名称的TEST_FOR_Name,为每个名称赋予唯一的值。

#define TEST_FOR_Joe 1
#define TEST_FOR_Ben 2
#define DO_TEST(NAME1, NAME2) DO_TEST_impl(NAME1, NAME2)
#define DO_TEST_impl(NAME1, NAME2) TEST_FOR_ ## NAME1 == TEST_FOR_ ## NAME2

#define NAME Ben

#include <iostream>

int main() {
  std::cout << "Hello!" << std::endl;
#if DO_TEST(NAME, Joe)
  std::cout << "Joe Found!" << std::endl;
#elif DO_TEST(NAME, Ben)
  std::cout << "Ben Found!" << std::endl;
#else
  std::cout << "Neither found!" << std::endl;
#endif
}

基本思想是,我们建立带有每个名称关联的唯一数字值的标记。如果找不到标记的值,则比较会失败,但否则它确保数字相同。


2
@sergej:假设JoeBen是类型:NAME var = {3};。如果#define NAME Joe,则无法正常工作。 - Mooing Duck
2
@sergej:你假设JoeBen可以定义为任意数字。如果这些符号代表有意义的内容或者已经是宏定义,那么你简单的方法就行不通了。而Charles的方法则不受影响。 - Mooing Duck
这个还能够适用于通过编译器选项-DName=Joe定义的宏名称吗? - Walter
@undur_gongor 你说得对极了!我漏掉了从 Name 改为 NAME 的变化。 - Walter

-1
相信你会发现在仅使用 C++ 中是无法实现的,有一些人通过工具链扩展找到了一些方法,但这并不可移植。 另一个用户提出了类似的问题: 这里

我也不知道,但是链接问题中未被接受的答案中的“工具链扩展”是一个幻想。请参见该答案的第三个评论以获取解释。 - rici

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接