我想知道在对有符号类型进行操作时检查右移是否算术的最便携方法是什么(例如 -2 >> 1
是否为 -1
) 在编译时。
我的想法是在编译时以某种方式检查它并能够检测到它,这样我就可以编译函数的不同版本(取决于运算符 >>>
是否真的是算术移位) .
通过阅读主题 Verifying that C / C++ signed right shift is arithmetic for a particular compiler?我想到了初始化一个标志
static const bool is_arithmetic_rs = (((signed int)-1)>>1) == ((signed int)-1));
并像这样在运行时测试它:
if (is_arithmetic_rs) {
// some fast algorithm using arithmetic right shifts (using >> operator)
} else {
// the same algorithm without arithmetic right shifts (much slower)
}
但是,如果可能的话,我想每次都避免这种分支。为简单起见,假设我想实现一个可移植的算术右移;如果我必须在每次调用函数时都检查它,这将对性能产生巨大影响,所以如果可能的话,我想在编译时进行。
如果没有可移植的方法来执行此检查,是否有一种方法可以通过尽力而为的方式进行检查,例如使用 ifdefs 检查特定的编译器/平台?
最佳答案
执行此类检查的最佳方法是例如GNU autotools做:
在您的目标平台上编译一个小程序并测试会发生什么
在头文件中设置适当的
#define
在您的源文件中包含该头文件
可选地,使用适当定义的宏,这样您的代码就不会因每件小事都被
#ifdef
指令弄得乱七八糟。编译你的主项目
这样一来,您就不必创建具有受支持功能的表以及每个硬件平台和操作系统在野外的各种怪癖 - 更不用说它们的组合了。但是,如果您不在您的目标上构建您的代码,您将必须用您的目标的预先提供的功能表/列表替换第一步。
您可能应该看看广泛使用的构建系统,例如 GNU autotools 或 CMake ,以便重用现有的宏和特定于平台的信息,避免创建自己的宏和重新发明轮子。
顺便说一句,现在任何体面的编译器都应该优化使用常量表达式的简单测试,因此在必要时使用运行时测试 - 可能通过宏 - 不应该对性能造成太大影响。您应该测试和分析您的代码以找出答案。
关于c++ - 编译时检查右移是否是有符号类型的算术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5123314/