编译器是否优化出净零位移位? [英] Do compilers optimize out net zero bit shifts?
问题描述
我在 .cpp
文件中有一些类似于以下代码块的代码(不允许张贴原始代码),我认为它是由 clang ++
编译的( Ubuntu clang版本3.5.2-3ubuntu1(标签/RELEASE_352/final)(基于LLVM 3.5.2)
).
看起来像 C
代码,因为我们正在使用 GoogleTest
来测试我们的 C
代码.无论如何:
I have some code like the following code block (I am not allowed to post the original code) inside a .cpp
file that I think is being compiled by clang++
(Ubuntu clang version 3.5.2-3ubuntu1 (tags/RELEASE_352/final) (based on LLVM 3.5.2)
).
It looks like C
code, because we are using GoogleTest
for testing our C
code. Anyways:
size_t const SHIFT = 4;
uint8_t var, var2;
/* Omitted: Code that sets var to, say 00011000 (base 2) */
var2 = var;
var = var << SHIFT >> SHIFT; // [1] result is 00011000 (base 2) (tested with printf)
var2 = var2 << SHIFT;
var2 = var2 >> SHIFT; // [2] result is 00001000 (base 2) (tested with printf)
现在,为什么注释 [1]
成立?我假设相应的行将导致高4位被清零.但是我发现这是不对的.该程序只是恢复原始值.
Now, why does comment [1]
hold true? I was assuming that the corresponding line would result in the top 4 bits being zeroed out. But I found out that this isn't true; the program simply restores the original value.
这是某种语言定义的行为,还是
clang
编译出了所谓的无用位移?
Is this some language defined behavior, or is
clang
compiling out a supposedly useless bit shift?
(我检查了关联性(假设使用此表在cppreference.com 上,基本操作符的关联性/优先级在 C ++
的版本之间也不会有所不同,并且在 C ++
和 C
的版本之间也可能不会有所不同,至少在'当前版本"),似乎 [1]
处的RHS表达式应该确实产生与以下两个语句相同的结果)
(I checked associativity (using this table on cppreference.com, assuming that associativity/precedence of basic operators won't differ between versions of C++
and probably not between C++
and C
either, at least not in 'current versions') and it seems like the RHS expression at [1]
should really yield the same result as the two following statements)
推荐答案
您看到的是整数促销的结果.在表达式中使用时,任何等级低于 int
的值将被提升为 int
.
What you are seeing is a result of integer promotions. Any value with a type of lower rank than int
, when used in an expression, is promoted to int
.
这在C标准
2 以下表达式可用于
int
或unsigned int
可能在的表达式中被使用:
2 The following may be used in an expression wherever an
int
orunsigned int
may be used:
- 具有整数类型(
int
或unsigned int
除外)的对象或表达式其整数转换等级小于或等于int
的等级,并且unsigned int
. -
_Bool
,int
,signed int
或unsigned int
类型的位字段. li>
- An object or expression with an integer type (other than
int
orunsigned int
) whose integer conversion rank is less than or equal to the rank ofint
andunsigned int
. - A bit-field of type
_Bool
,int
,signed int
, orunsigned int
.
如果 int
可以表示原始类型的所有值(受宽度限制,对于位字段),将值转换为 int
;否则,它将转换为 unsigned int
.这些称为整数促销.所有其他类型均未更改整数促销.
If an int
can represent all values of the original type (as restricted by the width, for a
bit-field), the value is converted to an int
; otherwise, it is converted to an unsigned int
. These are called the integer promotions. All other types are unchanged by the
integer promotions.
在这种情况下:
var = var << SHIFT >> SHIFT;
var
首先被提升为 int
.此类型至少为16位宽,最有可能为32位宽.因此,要操作的值是 0x00000018
.左移4将导致 0x00000180
,随后向右移位将导致 0x00000018
.
var
is first promoted to int
. This type is at least 16 bits wide, and most likely 32 bits wide. So the value being operated on is 0x00000018
. A left shift of 4 results in 0x00000180
, and subsequently right shifting results in 0x00000018
.
然后将结果存储在 uint_8
中.由于该值适合此类型的变量,因此无需进行转换,并且将存储 0x18
.
The result is then stored in a uint_8
. Since the value fits in a variable of this type, no conversion is required and 0x18
is stored.
这篇关于编译器是否优化出净零位移位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!