我遇到了无法在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标签当然必须是编译时常量,但是显然并非所有编译器都这样。该代码是不可移植的,我猜是未定义的或实现定义的行为,还是纯属错误!
显而易见的便携式解决方案具有效率和可维护性的缺点,因此我有两个问题:
为什么此代码不可移植-是什么使该宏在某些编译器中不能保持编译时常量?
是否存在一种可移植的解决方案,以从助记符字符串生成所需的编译时间常数?
在C ++ 11中,您可以使用一个constexpr
函数:
constexpr int CONST_MNEMONIC(const char* s)
{
return (static_cast<int>(s[2]) << 16) +
(static_cast<int>(s[1]) << 8) +
static_cast<int>(s[0]);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句