C++宏按序号展开

q7solyqu  于 2023-02-01  发布在  其他
关注(0)|答案(2)|浏览(122)

我有一段代码可以在不同的平台上编译,这些平台具有不同的功能(每个功能都由一个特定的define表示),我正在挠头如何执行下面的switch(int)语句,以保持"case(number):"有序和连续。

int funcParam;
switch(funcParam)
{
case 0: break;

case 1:break;

#ifdef FEATURE_1
case 2: break;
#endif // FEATURE_1

case 3: break;  // <<== problem here: 3 follows 1 if FEATURE_1 is not defined

#ifdef FEATURE_2
case 4: break; <<== problem here: 4 follows 2 if FEATURE_1 is not defined
#endif // FEATURE_2

#ifdef FEATURE_3
case 5: break; <<== problem here: 5 follows 2 or 3 or 4 depending on features
#endif // FEATURE_3
}

每个case代码块都是10行左右的代码块,我想这是无关紧要的,但是最好的解决方案是找到一种方法来发出代码,如下所示:

case NEXTNUM:

它将随着宏NEXTNUM的每次扩展而扩展到下一个序数。不知道它可能是如何编写的。
请记住,我使用的是相当老的编译器(C ++98,可以考虑C ++03)。
编辑:
最终发现了一个非常相似的问题:Auto-incrementing macro expansion,这归结为一个非常简单的解决方案,即使用枚举而不仅仅是普通数字。
谢谢你,拉狄克

wgx48brx

wgx48brx1#

创建等于0和1的变量,具体取决于功能是否启用。将这些变量添加到功能案例之后的案例中。

int main() {
    int funcParam;
    const int add_feature_1 = 
#ifdef FEATURE_1
        1
#else
        0
#endif
        ;
    const int add_feature_2 = 
#ifdef FEATURE_2
        1
#else
        0
#endif
        ;
    const int add_feature_3 = 
#ifdef FEATURE_3
        1
#else
        0
#endif
        ;
    switch(funcParam) {
    case 0: break;
    case 1: break;
#ifdef FEATURE_1
    case 2: break;
#endif
    case 2 + add_feature_1: break;
#ifdef FEATURE_2
    case 3 + add_feature_1: break;
#endif // FEATURE_2
#ifdef FEATURE_3
    case 3 + add_feature_1 + add_feature_2: break;
#endif // FEATURE_3
    }
}

考虑重构您的代码,以便必须定义FEATURE_X(我认为这更好),而不是将FEATURE_X定义为数字0或1。

#define FEATURE_1 0
#define FEATURE_2 1
#define FEATURE_3 0
int main() {
    int funcParam;
    switch(funcParam) {
    case 0: break;
    case 1: break;
#if FEATURE_1
    case 2: break;
#endif
    case 2 + FEATURE_1: break;
#if FEATURE_2
    case 3 + FEATURE_1: break;
#endif // FEATURE_2
#if FEATURE_3
    case 3 + FEATURE_1 + FEATURE_2: break;
#endif // FEATURE_3
    }
}

或者类似的组合,你应该明白了。

uplii1fm

uplii1fm2#

使用x1m2 n1,中的值,而不是case 0case 1...等;这些也是编译时常量,因此法律的的值为case
您可以将相同的#ifdef特征检查插入到enum定义中,然后枚举选项仍会被连续标记。
经验法则:
1.这样做并不能使任何东西变得更漂亮。老实说,启用或不启用一个特性可能都不会改变值函数交换--这只是丑陋和调试灾难的配方。所以,我质疑你的动机!
1.一个case几乎不需要任何成本。与其删除这些案例,你可能应该考虑当这种案例被触发时,正确的操作是什么。警告?系统关闭?
1.事实上,您没有在switch/case中使用enum,这确实是一个不好的迹象,而你依赖于案例仍然是连续编号是非常令人担忧的。使用神奇的数字常量本身就已经够糟糕的了--让它们在不同的特性集上有不同的含义会尖叫“已经犯了架构错误”。我会用一个枚举中的条目替换我所有的魔法数值,这样你会更开心。
最后:uff. C98. C03已经有20年的历史了。这是一个重要的bug修复版本,基本上什么都没有。你真的应该毫不犹豫地使用它。

相关问题