从文字字符串生成编译时常量整数
Generating a compile-time constant integer from a literal string
我对在ARM RealView编译器上正常工作的不可移植代码有问题,但VC++、GCC拒绝编译它,并且QAC++(一种静态分析工具)发出警告。
问题
我有一个系统,需要解析消息中的助记符标识符。助记符都是三个字符的8位ASCII字符串。为了简化和优化解析,而不是与助记字符串进行字符串比较,我将字符串打包为32位整数并进行整数比较。
此外,为了能够使用开关/大小写而不是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]);
}
它在这里用gcc 4.8和clang 3.4编译得很好…
在C++11中,您可以使用:
constexpr uint32_t CONST_MNEMONIC(const char (&s)[4])
{
return (uint32_t(s[2]) << 16) | (uint32_t(s[1]) << 8) | uint32_t(s[0]);
}
相关文章:
- 为什么乘以常量有符号整数分数没有优化?
- 初始化不是整数的巨大常量多维数组的最佳方法是什么?
- 如何在满足常量表达式的同时将整数传递给指针,传递给 std::array<double、integer>?
- 有什么区别 - 常量 int x = 5000;和常量整数 x = 50'00;在C++?
- 常量整数变量和数字的不同类型推导
- 错误 C2864:'element::next':只能在类 (STRUCT) 中初始化静态常量整数数据成员
- C++整数常量表达式定义
- C++ 计算编译时常量,同时防止整数常量溢出
- 当我要修改指针到常量整数时,为什么我的编译器不显示错误
- 包含 comptime 断言的整数常量表达式宏
- 用于定义公共变量静态常量整数的C++标准
- 将非常量整数从 in C++传递给模板参数
- 从文字字符串生成编译时常量整数
- 当我们在 c++ 中将常量整数引用分配给整数指针时,行为是什么
- 为什么允许常量整数指针指向非常量整数
- 存储在静态常量整数 (C++) 中的对数函数的错误返回值
- 常量整数意外更改C++
- 常量整数提升规则
- 为什么不通过获取内联定义的静态常量整数成员变量的地址来违反 ODR?
- 简单类中的常量整数特性