我有一段代码可以在不同的平台上编译,这些平台具有不同的功能(每个功能都由一个特定的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,这归结为一个非常简单的解决方案,即使用枚举而不仅仅是普通数字。
谢谢你,拉狄克
2条答案
按热度按时间wgx48brx1#
创建等于0和1的变量,具体取决于功能是否启用。将这些变量添加到功能案例之后的案例中。
考虑重构您的代码,以便必须定义FEATURE_X(我认为这更好),而不是将FEATURE_X定义为数字0或1。
或者类似的组合,你应该明白了。
uplii1fm2#
使用x1m2 n1,中的值,而不是
case 0
、case 1
...等;这些也是编译时常量,因此法律的的值为case
。您可以将相同的
#ifdef
特征检查插入到enum
定义中,然后枚举选项仍会被连续标记。经验法则:
1.这样做并不能使任何东西变得更漂亮。老实说,启用或不启用一个特性可能都不会改变值函数交换--这只是丑陋和调试灾难的配方。所以,我质疑你的动机!
1.一个
case
几乎不需要任何成本。与其删除这些案例,你可能应该考虑当这种案例被触发时,正确的操作是什么。警告?系统关闭?1.事实上,您没有在
switch
/case
中使用enum
,这确实是一个不好的迹象,而你依赖于案例仍然是连续编号是非常令人担忧的。使用神奇的数字常量本身就已经够糟糕的了--让它们在不同的特性集上有不同的含义会尖叫“已经犯了架构错误”。我会用一个枚举中的条目替换我所有的魔法数值,这样你会更开心。最后:uff. C98. C03已经有20年的历史了。这是一个重要的bug修复版本,基本上什么都没有。你真的应该毫不犹豫地使用它。