标签: integer-promotion

当二元运算符两边的签名不同时,促销规则如何工作?

考虑以下程序:

// http://ideone.com/4I0dT
#include <limits>
#include <iostream>

int main()
{
    int max = std::numeric_limits<int>::max();
    unsigned int one = 1;
    unsigned int result = max + one;
    std::cout << result;
}
Run Code Online (Sandbox Code Playgroud)

// http://ideone.com/UBuFZ
#include <limits>
#include <iostream>

int main()
{
    unsigned int us = 42;
    int neg = -43;
    int result = us + neg;
    std::cout << result;
}
Run Code Online (Sandbox Code Playgroud)

+运算符如何"知道"返回哪个正确的类型?一般的规则是把所有的参数转换为最广泛的类型,但在这里没有明确的"赢家"之间intunsigned int.在第一种情况下,unsigned int必须选择作为结果operator+,因为我得到了结果2147483648.在第二种情况下,它必须选择int,因为我得到了结果-1.然而,在一般情况下,我没有看到这是如何可判定的.这是我看到的未定义的行为还是其他什么?

c++ arithmetic-expressions overflow integer-promotion

25
推荐指数
2
解决办法
8374
查看次数

如何在C中评估换档操作符?

当我使用shift进行操作时,我最近发现了一种(奇怪的)行为>> <<!

为了解释它,让我编写这个小的可运行代码,执行两个应该相同的操作(在我的理解中),但我对不同的结果感到惊讶!

#include <stdio.h>

int main(void) {
    unsigned char a=0x05, b=0x05;

    // first operation
    a = ((a<<7)>>7);

    // second operation
    b <<= 7;
    b >>= 7;

    printf("a=%X b=%X\n", a, b);
    return 0;
} 
Run Code Online (Sandbox Code Playgroud)

跑步时,a = 5b = 1.我希望它们都等于1!有人可以解释为什么我得到这样的结果?

PS:在我的环境中,大小unsigned char为1个字节

c bit-shift integer-promotion

24
推荐指数
3
解决办法
1918
查看次数

Why doesn't a negative number modulo a vector size give a negative number?

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
  vector<int> v = {1, 2, 3, 4, 5, 6, 7};
  int i = -4;

  cout << i << endl;
  cout << v.size() << endl;
  cout << i % v.size() << endl;
  cout << -4 % 7 << endl;
}
Run Code Online (Sandbox Code Playgroud)

The above code prints:

-4
7
5
-4
Run Code Online (Sandbox Code Playgroud)

Can someone please explain why i % v.size() prints 5 instead of -4? I'm guessing it has something to do …

c++ integer-promotion modulus

23
推荐指数
3
解决办法
1146
查看次数

为什么unsigned short(multiply)unsigned short转换为signed int?

为什么unsigned short * unsigned short转换为intC++ 11?

int太小的这行代码为证明办理最大值.

cout << USHRT_MAX * USHRT_MAX << endl;
Run Code Online (Sandbox Code Playgroud)

在MinGW 4.9.2上溢出

-131071
Run Code Online (Sandbox Code Playgroud)

因为(来源)

USHRT_MAX = 65535(2 ^ 16-1)或更高*

INT_MAX = 32767(2 ^ 15-1)或更高*

(2^16-1)*(2^16-1) = ~2^32.


我应该期待这个解决方案有什么问题吗?

unsigned u = static_cast<unsigned>(t*t);
Run Code Online (Sandbox Code Playgroud)

这个计划

unsigned short t;
cout<<typeid(t).name()<<endl;
cout<<typeid(t*t).name()<<endl;
Run Code Online (Sandbox Code Playgroud)

给出输出

t
i
Run Code Online (Sandbox Code Playgroud)

gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)
gcc version 4.8.2 (GCC)
MinGW 4.9.2
Run Code Online (Sandbox Code Playgroud)

g++ p.cpp
g++ -std=c++11 p.cpp
Run Code Online (Sandbox Code Playgroud)

这证明了t*t …

c++ types type-conversion integer-promotion c++11

22
推荐指数
4
解决办法
4619
查看次数

如何强制将int的大小用于调试目的?

对于正在开发的软件,我有两种构建方式,一种是针对int大小为16位的嵌入式系统,另一种是针对int大小为32位的台式机进行测试。我使用的是固定宽度的整数类型<stdint.h>,但整数提升规则仍取决于int的大小。

理想情况下,由于整数提升,我希望打印以下代码65281(将整数提升为16位)而不是4294967041(将整数提升为32位),以使其与嵌入式系统上的行为完全匹配。我要确保在台式机测试期间给出一个答案的代码与嵌入式系统上给出的答案完全相同。对于GCC或Clang的解决方案都可以。

#include <stdio.h>
#include <stdint.h>

int main(void){
    uint8_t a = 0;
    uint8_t b = -1;

    printf("%u\n", a - b);

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

编辑:

我给出的示例可能不是最好的示例,但是我确实希望整数提升为16位而不是32位。请看以下示例:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void){
    uint16_t a = 0;
    uint16_t b = 1;
    uint16_t c = a - 2; // "-2": 65534
    uint16_t d = (a - b) / (a - c);

    printf("%" PRIu16 "\n", d);

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

输出是0在32位系统上,这是因为在提升为(signed)int而不是后从整数除法截断了32767

到目前为止,最好的答案似乎是使用仿真器,这不是我想要的,但是我认为确实是有道理的。从理论上来说,编译器似乎可以生成行为,就像int的大小为16位一样,但是我想实践中没有简单的方法可能并不奇怪,对这种模式和任何必要的运行时支持的需求可能不大。

编辑2: …

c gcc clang integer-promotion

22
推荐指数
2
解决办法
2432
查看次数

移位运算符的结果类型是什么?

考虑以下清单:

#include <type_traits>
#include <cstdint>

static_assert(std::is_same_v<decltype(31), int32_t>);
static_assert(std::is_same_v<decltype(31u), uint32_t>);

static_assert(std::is_same_v<decltype((signed char)1 << 1), int32_t>);
static_assert(std::is_same_v<decltype((signed char)1 << 1u), int32_t>);
static_assert(std::is_same_v<decltype((unsigned char)1 << 1), int32_t>);
// Signed result for unsigned char
static_assert(std::is_same_v<decltype((unsigned char)1 << 1u), int32_t>);
// But unsigned for uint32_t
static_assert(std::is_same_v<decltype(1u << 1u), uint32_t>);
Run Code Online (Sandbox Code Playgroud)

它可以与 GCC 和 Clang 很好地编译。我很困惑operator<<(uint8_t, uint32_t)。为什么要签署结果?

c++ types bit-shift integer-promotion

22
推荐指数
2
解决办法
2117
查看次数

添加两个字符会产生int

我做了一个简单的程序,用GCC 4.4/4.5编译如下:

int main ()
{
  char u = 10;
  char x = 'x';
  char i = u + x;

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

g ++ -c -Wconversion a.cpp

我有以下内容:

a.cpp: In function ‘int main()’:
a.cpp:5:16: warning: conversion to ‘char’ from ‘int’ may alter its value
Run Code Online (Sandbox Code Playgroud)

我为以下代码得到了同样的警告:

  unsigned short u = 10;
  unsigned short x = 0;
  unsigned short i = u + x;

a.cpp: In function ‘int main()’:
a.cpp:5:16: warning: conversion to ‘short unsigned int’ from ‘int’ may alter its …
Run Code Online (Sandbox Code Playgroud)

c++ integer integer-overflow integer-promotion

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

是否有一个双重推动等式中的每个int加倍?

是否存在一个浮点数据类型(例如double)确保所有+, - ,*,/,%等数学运算都假定为双操作数?

如果故事比这更复杂,是否有描述这些规则的资源?我不应该问这样的问题,总是明确地转换intdouble当公式的结果double.这是我正在考虑的一些方程式.我故意不在我的系统上编译和运行,因为这是可能依赖于编译器的类型.

int a(1), b(2), c(3);
double d(4.);
double result1 = a + b/d + c; // equal to 4 or to 4.5?
double result2 = (a + b)/d + c; // equal to 3 or to 3.75?    
double result3 = a/b + d; // equal to 4 or to 4.5?
Run Code Online (Sandbox Code Playgroud)

c++ floating-point type-conversion integer-promotion

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

为什么不是common_type <long,unsigned long> :: type = long long?

common_type<long, unsigned long>::typeunsigned long因为关于积分推广后的操作数标准说...

[...]如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则带有符号整数类型的操作数应转换为具有无符号整数类型的操作数的类型

不要调用整数提升系统错误,但似乎有一个更大的有符号整数类型,它可以表示应该使用的有符号和无符号操作数的范围.

我知道有些平台可能长==很长,在这种情况下上述规则可以生效.但如果一个更大的符号整数类型可用,不应该应用它呢?

c++ integer-promotion language-lawyer

20
推荐指数
1
解决办法
997
查看次数

为什么auto被推导为int而不是uint16_t

我有以下代码:

uint16_t getLastMarker(const std::string &number);
...
const auto msgMarker = getLastMarker(msg.number) + static_cast<uint16_t>(1);
static_assert(std::is_same<decltype(msgMarker), const int>::value, "Should fail");
static_assert(std::is_same<decltype(msgMarker), const uint16_t>::value, "Should not fail");
Run Code Online (Sandbox Code Playgroud)

我希望第一个断言会失败而第二个断言不会失败.然而,gcc 4.9.2clang 3.6做相反的事情.如果我在我的代码中使用uint16_t而不是auto,则正确的断言失败而另一个成功.

PS最初我只是1代替static_cast<uint16_t>(1)并且认为问题是由数字文字1具有int类型但错误断言甚至在此处显式转换后失败的事实引起的.

c++ integer-promotion auto c++11

19
推荐指数
2
解决办法
846
查看次数