【发布时间】:2011-11-29 15:22:06
【问题描述】:
当问到如何做 wrapped N bit signed subtraction 的问题时,我得到了以下答案:
template<int bits>
int
sub_wrap( int v, int s )
{
struct Bits { signed int r: bits; } tmp;
tmp.r = v - s;
return tmp.r;
}
这很简洁,但是编译器将如何实现呢?从this question 我收集到访问位字段与手动操作或多或少相同,但是当与本示例中的算术结合使用时呢?它会像手动旋转位一样快吗?
如果有人想具体一点,“编译器”角色的“gcc”答案会很好。我已经尝试阅读生成的程序集,但它目前超出了我的范围。
【问题讨论】:
-
对于它的价值来说,这比手动编码的位旋转更难以阅读,即使它提高了性能我也会避免使用它(当然,除非这个单件位-杂乱无章的代码非常重要,它是性能的唯一瓶颈)。
-
如果
v-s的值不能存储在tmp.r中,我认为这实际上会调用未定义的行为(这意味着无论如何都不能保证它的位环绕效果)。 -
唯一知道的方法是阅读编译器生成的汇编代码。
-
@AndréCaron 我不太了解“不可读”部分。这个变体清楚而准确地表明我们想要一个超过
bits位的结果。手工编码的旋转依赖于对某些编程模式的识别;大多数程序员可能不太熟悉的模式。因此,如果在生产代码中使用它需要大量注释(因为这个版本可以在没有注释的情况下进入)。 -
@JamesKanze:这个版本需要熟悉这种很少遇到的语法,这也是大多数程序员不太熟悉的编程模式,我不知道哪个鲜为人知。但是,
(v-s) & ((1<<bits)-1)和一条评论说“将v-s截断为bits位”在我看来比使用位字段和隐式(可能不可靠)截断操作的本地struct更明确.正如 Python 的禅宗所说,“显式胜于隐式”。
标签: c++ gcc bit-manipulation bit-fields