基于宏中传递的字符串的条件编译

Conditional compilation based on string passed in macro

本文关键字:字符串 编译 条件 于宏中      更新时间:2023-10-16

我有一个形式为的宏

#define SAMPLE_MACRO(x) somefunction(x)

我用字符串作为参数调用宏:

SAMPLE_MACRO("abc");
SAMPLE_MACRO("bbe");
SAMPLE_MACRO("ccb");
SAMPLE_MACRO("axx");

有没有可能让预处理器解析字符串,这样如果假设它以"a"开头(在上面的例子中是字符串"abc"answers"axx"(,宏就会调用其他函数而不是函数((?换句话说,我不想在运行时执行并比较字符串的宏中添加"if"语句,但我希望宏根据编译时指定的字符串参数具有不同的行为。我认为这可能涉及到在宏中添加一些#ifdef。这在C++11中可能吗?

我不这么认为。您可以从参数名称创建字符串,但不能解析参数的内容。

听起来你基本上会为每个字符串条件创建一个不同的宏,所以最简单的方法是为每个条件使用不同的名称,如:

#define SAMPLE_MACRO(x) somefunction(x)
#define SAMPLE_MACRO_A(x) otherfunction(x)

如果宏是多行,并且只希望单行不同,一种方法是将函数名称作为宏参数传递:

#define SAMPLE_MACRO(f, x) { 
...
f(x);
...
}

可以称之为:

SAMPLE_MACRO(otherfunction, "abc");
SAMPLE_MACRO(somefunction, "bbe");

另一种选择是为其他行制作宏,并在特定宏中使用这些宏:

#define SAMPLE_MACRO_PRE(x) ...
#define SAMPLE_MACRO_POST(x) ...
#define SAMPEL_MACRO(x) { 
SAMPLE_MACRO_PRE(X); 
somefunction(x); 
SAMPLE_MACRO_POST(x); 
}
#define SAMPEL_MACRO_A(x) { 
SAMPLE_MACRO_PRE(X); 
otherfunction(x); 
SAMPLE_MACRO_POST(x); 
}

这些都适用于C。如果您想面向对象,可以考虑创建类来处理字符串中的差异,而不是宏。从基类型继承,并具有.somefunction((成员函数的不同实现。正确的对象定向可以消除许多switch((或级联if((语句。

听起来你试图过早地优化某些东西。如果是这种情况,那么应该注意的是,你实际上并不需要。由于数据是恒定的,编译器应该简单地优化条件语句。

以下编译没有任何条件分支,

#include <iostream>
using namespace std;
#define SAMPLE_MACRO(x) (x[0] == 'a' ? somefunction1(x) : somefunction2(x))
void somefunction1(const char* arg){
std::cout << "fn1 " << arg << std::endl;
}
void somefunction2(const char* arg){
std::cout << "fn2 " <<  arg << std::endl;
}
int main() {
SAMPLE_MACRO("abc");
SAMPLE_MACRO("def");
return 0;
}

main:
sub     rsp, 8
mov     edi, OFFSET FLAT:.LC2
call    somefunction1(char const*)
mov     edi, OFFSET FLAT:.LC3
call    somefunction2(char const*)
xor     eax, eax
add     rsp, 8
ret

Godbolt演示