我有一个问题,涉及到非可移植的代码。在ARM RealView编译器上可以正常运行,但是VC ++,GCC拒绝编译它,QAC ++(静态分析工具)发出警告。
问题
我的系统需要解析消息中的助记符标识符。这些助记符都是三个字符的8位ASCII字符串。为了简化和优化解析,而不是对助记符字符串执行字符串比较,我将字符串打包成32位整数并执行整数比较。
为了能够使用switch / case而不是if-elseif链,我有一个宏,它接受文字字符串并生成关联的整数,在ARM RealView中,这是一个编译时常量,但在GCC x86 / Linux或VC ++ / Windows中则不是:
// Note: Do not change C cast to static_cast because compiler complains when used in switch/case
#define CONST_MNEMONIC( mn ) ((uint32_t)(((#mn)[2]<<16)|((#mn)[1]<<8)|((#mn)[0])))
然后在ARM目标代码中使用如下:
switch( packed_mnemonic )
{
case CONST_MNEMONIC(RST) :
...
break ;
case CONST_MNEMONIC(SSD) :
...
break ;
case CONST_MNEMONIC(DEL) :
...
break ;
default:
...
break ;
}
当然,case标签必须是一个编译时常量,但显然并非所有编译器都是这样。该代码并不具备可移植性,可能产生未定义或实现相关行为,甚至是错误的!
问题
明显的便携式解决方案在效率和可维护性方面存在缺点,因此我有两个问题:
为什么这段代码不具备可移植性 - 什么使得宏在某些编译器中不是编译时常量?
是否有一种可移植的解决方案,可以从助记符字符串生成所需的编译时常量?
#mn
时,你创建了字符串字面量“mn”。要使用实际传递给宏的字符串字面量,请删除字符串化操作。 - Some programmer dudechar RST[],SSD[],DEL[]
?你的代码缺少重要部分,这使得分析问题变得困难。 - barak manos