我有一些代码,如下面的代码块(我不允许发布原始代码).cpp
我认为正在编译的文件clang++
(Ubuntu clang version 3.5.2-3ubuntu1 (tags/RELEASE_352/final) (based on LLVM 3.5.2)
).
看起来像C
代码,因为我们正在使用GoogleTest
用于测试我们的C
代码。无论如何:
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 位被清零。但我发现这不是真的;该程序只是恢复原始值。
这是某种语言定义的行为,还是clang
编译出一个据称无用的位移位?
(我检查了关联性(使用cppreference.com 上的此表 http://en.cppreference.com/w/c/language/operator_precedence,假设基本运算符的结合性/优先级在不同版本之间没有差异C++
并且可能不在之间C++
and C
要么,至少不是在“当前版本”中),并且看起来像 RHS 表达式[1]
实际上应该产生与以下两个语句相同的结果)
你所看到的结果是整数促销。任何等级低于类型的值int
,当在表达式中使用时,被提升为int
.
这在第 6.3.1.1 节中有详细介绍。C标准 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
2无论何时,都可以在表达式中使用以下内容int
or unsigned int
可能
使用:
- 具有整数类型的对象或表达式(除了
int
or unsigned int
)
其整数转换等级小于或等于int
and
unsigned int
.
- 类型的位域
_Bool
, int
, signed int
, or unsigned int
.
If an int
可以表示原始类型的所有值(受宽度限制,对于
位域),该值被转换为int
;否则,它会被转换为unsigned int
。这些被称为整数促销。所有其他类型均未改变
整数促销。
在这种情况下:
var = var << SHIFT >> SHIFT;
var
首先晋升为int
。该类型至少为 16 位宽,最有可能为 32 位宽。所以正在操作的值是0x00000018
。左移 4 的结果是0x00000180
,随后右移导致0x00000018
.
然后结果存储在uint_8
。由于该值适合这种类型的变量,因此不需要转换0x18
被储存了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)