相关疑难解决方法(0)

为什么常量表达式会排除未定义的行为?

我正在研究核心常量表达式*中允许的内容,这在C++标准草案的5.19 常量表达式2段中有所描述:

条件表达式是核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式(3.2),但是未评估的逻辑AND(5.14),逻辑OR(5.15)和条件(5.16)操作的子表达式不考虑[注意:重载的运算符调用函数.-end note]:

并列出随后的子弹中的排除项并包括(强调我的):

- 具有未定义行为的操作 [注意:包括,例如,有符号整数溢出(第5条),某些指针算术(5.7),除零(5.6)或某些移位操作(5.8) - 结束注释];

?为什么常量表达式需要此子句来涵盖未定义的行为常量表达式是否有一些特殊的东西需要未定义的行为才能在排除中进行特殊划分?

拥有这个条款是否给了我们没有它的任何优势或工具?

作为参考,这看起来像广义常量表达式提案的最新修订版.

c++ sfinae undefined-behavior constexpr c++11

46
推荐指数
3
解决办法
2752
查看次数

为什么二进制等效计算不正确?

我编写了以下程序来输出一个整数的二进制等价物(我检查了我的系统上的int是4个字节)它是4个字节.但输出并不合适.代码是:

#include<iostream>
#include<iomanip>
using namespace std;

void printBinary(int k){
    for(int i = 0; i <= 31; i++){
        if(k & ((1 << 31) >> i))
            cout << "1";
        else 
            cout << "0";
    }
}

int main(){
    printBinary(12);
}
Run Code Online (Sandbox Code Playgroud)

我哪里弄错了?

c++ binary

18
推荐指数
2
解决办法
1572
查看次数

左移(<<)是C++ 11中的负整数未定义行为吗?

int在C++ 11中左移一个负的未定义行为?

这里的相关标准段落来自5.8:

2/E1 << E2的值是E1左移E2位的位置; 空位是零填充的.如果E1具有无符号类型,则结果的值为E1×2E2,比结果类型中可表示的最大值减少一个模数.否则,如果E1具有有符号类型和非负值,并且在结果类型中可以表示E1×2E2,那么这就是结果值; 否则,行为未定义.

令我困惑的部分是:

否则,如果E1具有有符号类型和非负值,并且在结果类型中可以表示E1×2E2,那么这就是结果值; 否则,行为未定义.

这应该被解释为左移任何负数是UB吗?或者它只是意味着如果你的LS为负数且结果不适合结果类型,那么它是UB?

而且,前面的条款说:

1 /移位运算符<<和>>组从左到右.shift-expression:additive-expression shift-expression << additive-expression shift-expression >> additive-expression

操作数应为整数或无范围的枚举类型,并执行整体促销.

结果的类型是提升的左操作数的类型.如果右操作数为负数,或者大于或等于提升左操作数的位长度,则行为未定义.

这使得明确表示对其中一个操作数使用负数是UB.如果UB对另一个操作数使用负数,我希望在这里也要明确.

所以,底线是:

-1 << 1
Run Code Online (Sandbox Code Playgroud)

未定义的行为?


@Angew 提供了对Standardese的psudocode解释,它简洁地表达了一种可能(可能)有效的解释.其他人质疑这个问题是否真的与"行为未定义"的语言的适用性相比,而我们(StackOverflow)使用了"未定义行为"这一短语.这个编辑是为了提供一些我想要问的更多说明.

@Angew对Standardese的解释是:

if (typeof(E1) == unsigned integral)
  value = E1 * 2^E2 % blah blah;
else if (typeof(E1) == signed integral && E1 >= 0 && representable(E1 * 2^E2))
  value = E1 * 2^E2;
else
  value = undefined;
Run Code Online (Sandbox Code Playgroud)

这个问题真正归结为这个 - …

c++ language-lawyer c++11

13
推荐指数
2
解决办法
4210
查看次数

为什么C++没有将INT_MIN定义为(1 << 31)

我理解为什么C++将INT_MIN定义为(-2147483647-1),但为什么它们不使用1 << 31?这样可以防止溢出并且易于理解.

c++ numeric-limits

4
推荐指数
1
解决办法
524
查看次数

定义(1 << 31)还是使用0x80000000?结果不同

#define SCALE (1 << 31)

#define fix_Q31_80(x) ( (int) ( (float)(x)*(float)0x80000000 ) )
#define fix_Q31_SC(x) ( (int) ( (float)(x)*(float)SCALE      ) )

int main()
{
    int fix_80 = fix_Q31_80(0.5f);
    int fix_sc = fix_Q31_SC(0.5f);
}
Run Code Online (Sandbox Code Playgroud)

为什么价值观fix_80fix_sc不同?

fix_80 == Hex:0x40000000
fix_sc == Hex:0xc0000000
Run Code Online (Sandbox Code Playgroud)

c casting

4
推荐指数
2
解决办法
3084
查看次数

为什么是0x7FFFFFFFull | (1 << 31)在C++中返回0xFFFFFFFFFFFFFFFF?

当我这样做(0x7fffffff | 0x8000000)时,我得到0xffffffffffffffff而不是预期的0xffffffff.我错过了什么?

一些示例代码和输出来说明我的问题.

码:

#include <iostream>

using namespace std;

int main()
{
        unsigned long long val = 0;

        for (int i = 0; i < 64; i++) {
                val |= 0x1 << i;
                cout << i << ": " << std::hex << val << std::dec << endl;
        }

        return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

0: 1
1: 3
2: 7
3: f
4: 1f
5: 3f
6: 7f
7: ff
8: 1ff
9: 3ff
10: 7ff
11: fff
12: 1fff
13: …

c++ bit-manipulation bit-shift bitwise-operators

2
推荐指数
1
解决办法
418
查看次数

为什么将a = 1向左移31位然后向右移31位,它变为-1

特定

int a = 1;(00000000000000000000000000000001),

我做的只是

a=(a<<31)>>31;
Run Code Online (Sandbox Code Playgroud)

我认为a应该仍然1在这个陈述之后(我认为没有改变).但事实证明是-1(11111111111111111111111111111111).谁知道为什么?

c++ bit-manipulation

-1
推荐指数
1
解决办法
2032
查看次数