位移位编译器错误或极端情况
Bit shift compiler bug or a corner case?
以下代码输出0,1,32,33。这至少可以说是违反直觉的。但是,如果我将文字1替换为类型声明常量"ONE",则循环运行良好。
这是与gcc 4.6.2和-std=c++0x。
#include<iostream>
#include<cstdint>
using namespace std;
int main()
{
int64_t bitmask = 3;
int64_t k;
const int64_t ONE = 1;
cout<<"bitmask = "<<bitmask<<endl;
for(k=0; k<64; k++)
{
if(bitmask & (1<<k))
{
cout<<"k="<<k<<endl;
}
}
return 0;
}
编辑问题:正如Ben指出的,默认情况下,1被视为32位宽。为什么它没有被提升到64位而它的合作操作数是64位。
<解决方案/strong>
。& lt; & lt;不要求每一方都有相同的类型。毕竟,当最大的移位可以在char中使用时,为什么要将右侧设置为int64_t呢?提升只在处理算术运算符时发生,而不是在处理所有运算符时。
摘自Bill下面的评论
这是一个问题:(1<<k)
.
1
是一个整型字面值,适合于int
。
如果int
在您的平台上小于64位,那么当k
较大时,(1<<k)
将在循环结束时具有未定义的行为。在你的例子中,编译器使用的是Intel的位移指令,未定义的行为就像Intel定义的大于操作数大小的移位一样——高位被忽略。
你可能想要(1LL<<k)
标准内容(expr.shift
章节5.8):
操作数必须为整型或无作用域枚举类型,并执行整型提升。结果的类型是提升后的左操作数的类型。如果右操作数为负,或大于或等于提升后的左操作数的位长度,则未定义该行为。
这与"执行通常的算术转换"的措辞形成对比算术或枚举类型的操作数",用于加法和减法运算符
该语言在c++ 03和c++ 11之间没有变化
相关文章:
- 没有可行的过载'='错误,可能导致这种情况的原因是什么?
- 特定情况下的分段错误
- MSVC 在不知道类型的情况下评估上下文(和错误)
- 如何在没有打印语句的情况下报告用户输入错误
- 在最坏的情况下试验快速排序.它运行良好,但在最坏的情况下发生未知错误.我想
- 如何在不设置 ulimit -n 的情况下解决套接字程序打开太多文件的错误
- 调整向量大小并检索值,这是否正确或在任何情况下都可能导致段错误?
- 如果 return 语句在带括号的循环中,错误可能会到达非 void 函数的末尾,但不会显示在没有括号的循环的情况下
- 我需要在不使用前向声明的情况下相互包含两个头文件,导致"incomplete type"错误
- 在存在错误代码的情况下输出参数与 NRVO
- 合成错误不知道为什么会发生这种情况,请检查一下并告诉我这是我的编码还是视觉工作室
- 我是否需要处理以下代码中的任何错误情况?
- 如何处理加载错误的共享库版本的情况
- 对象无法访问其私人数据.错误:在这种情况下私有
- 在这种情况下如何解决?语法错误:在"* "node" ?
- 对于特定情况的整数溢出似乎是由整数溢出引起的错误
- 如何编写一个通用函数,该通用函数在没有任何条件和条件的情况下工作(无论是真实和错误)
- 错误:在 DLSYSM 的情况下,从“void*”到“void (*)()”的转换无效
- 我的调试器说我有一个隔离错误错误,但无法告诉我在哪里,在非常特殊的情况下发生
- 为什么在这种情况下编制动态库错误