我想知道在对有符号类型进行操作时检查右移是否是算术的最便携的方法是什么(例如是否-2 >> 1
is -1
) 在编译时。
我的想法是在编译时以某种方式检查这一点并能够检测到这一点,这样我就可以编译该函数的不同版本(取决于运算符是否>>
是否真的是算术移位)。
通过阅读主题验证 C / C++ 有符号右移对于特定编译器来说是算术吗? https://stackoverflow.com/questions/1597704/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 自动工具 http://en.wikipedia.org/wiki/GNU_build_system do:
这样,您就不必创建具有支持的功能以及每个硬件平台和操作系统的各种怪癖的表 - 更不用说它们的组合了。但是,如果您没有在目标上构建代码,那么您will必须用针对您的目标预先提供的功能表/列表来替换第一步。
您可能应该看看广泛使用的构建系统,例如 GNU autotools 或CMake http://www.cmake.org/,以便重用现有的宏和特定于平台的信息,并避免必须创建自己的宏和重新发明轮子。
顺便说一句,现在任何像样的编译器都应该优化带有常量表达式的简单测试,因此在必要时使用运行时测试(也许通过宏)不会对性能造成太大影响。您应该测试并分析您的代码以找出答案。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)