相关疑难解决方法(0)

警告 - 有符号和无符号整数表达式之间的比较

我目前正在使用Accelerated C++,并在练习2-3中遇到了一个问题.

程序的快速概述 - 程序基本上采用名称,然后在星号框架内显示问候语 - 即Hello!被*的框架包围着.

练习 - 在示例程序中,作者用于const int确定问候语和星号之间的填充(空格).然后,作为练习的一部分,他们要求读者询问用户输入他们想要填充的大小.

所有这一切似乎都很容易,我继续向用户询问两个整数(int)并存储它们并更改程序以使用这些整数,删除作者使用的整数,编译时虽然得到以下警告;

Exercise2-3.cpp:46:warning:有符号和无符号整数表达式之间的比较

经过一些研究后,似乎是因为代码试图将上述整数(int)之一与a进行比较string::size_type,这很好.但我想知道 - 这是否意味着我应该改变其中一个整数 unsigned int?明确说明我的整数是签名还是未签名是否很重要?

 cout << "Please enter the size of the frame between top and bottom you would like ";
 int padtopbottom;
 cin >> padtopbottom;

 cout << "Please enter size of the frame from each side you would like: ";
 unsigned int padsides; 
 cin >> padsides;

 string::size_type c = 0; // definition of c …
Run Code Online (Sandbox Code Playgroud)

c++ unsigned-integer

66
推荐指数
3
解决办法
17万
查看次数

C++隐式转换(有符号+无符号)

我理解,对于隐式转换,如果我们有无符号类型操作数和带符号类型操作数,并且无符号操作数的类型与带符号操作数的类型相同(或更大),则将转换带符号操作数未签名.

所以:

unsigned int u = 10;  
signed int s = -8;

std::cout << s + u << std::endl;

//prints 2 because it will convert `s` to `unsigned int`, now `s` has the value
//4294967288, then it will add `u` to it, which is an out-of-range value, so,
//in my machine, `4294967298 % 4294967296 = 2`
Run Code Online (Sandbox Code Playgroud)

我不明白 - 我读到如果签名操作数的类型比无符号操作数大:

  • 如果无符号类型中的所有值都适合较大的类型,则无符号操作数将转换为有符号类型

  • 如果无符号类型中的值不适合较大的类型,则带符号的操作数将转换为无符号类型

所以在以下代码中:

signed long long s = -8;
unsigned int u = 10;
std::cout << s + u << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ arithmetic-expressions type-conversion unsigned-integer

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

未签名的签名转换

考虑以下:

#include <iostream>

int main() {

    unsigned int x = 3;
    unsigned int y = 5;

    std::cout << "a: " << x - y        << std::endl;

    std::cout << "b: " << ((int)x) - y << std::endl;

    std::cout << "c: " << x - ((int)y) << std::endl;

    std::cout << "d: " << ((int)x) - ((int)y) << std::endl;

}

$ g++ -Wconversion -Wall uint_stackoverflow.cc -o uint_stackoverflow && ./uint_stackoverflow
a: 4294967294
b: 4294967294
c: 4294967294
d: -2
Run Code Online (Sandbox Code Playgroud)

我理解为什么"a"没有给出预期的结果.但为什么"b"和"c"失败让我感到困惑.对于"b",我认为在将"x"转换为"int"后,结果将再次为"int".

你能开导我吗?

编辑:编译器不应警告?g ++(Ubuntu/Linaro 4.4.4-14ubuntu5)4.4.5

谢谢, …

c++

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

阈值是绝对值

我有以下功能:

char f1( int a, unsigned b ) { return abs(a) <= b; }
Run Code Online (Sandbox Code Playgroud)

对于执行速度,我想重写如下:

char f2( int a, unsigned b ) { return (unsigned)(a+b) <= 2*b; } // redundant cast
Run Code Online (Sandbox Code Playgroud)

或者使用此签名,即使对于非负面也可能具有微妙含义b:

char f3( int a, int b )      { return (unsigned)(a+b) <= 2*b; }
Run Code Online (Sandbox Code Playgroud)

这两种替代方案都可以在一个平台上进行简单的测试,但我需要便携式.假设非负b且没有溢出风险,这是典型硬件和C编译器的有效优化吗?它对C++也有效吗?


注意:作为C++在gcc 4.8 x86_64上使用-O3,f1()使用6个机器指令并f2()使用4.指令f3()与那些相同f2().同样感兴趣的是:如果b以文字形式给出,则两个函数都编译为3条指令,这些指令直接映射到指定的操作f2().

c c++ micro-optimization undefined-behavior language-lawyer

6
推荐指数
1
解决办法
341
查看次数

整数下溢导致模运算失败

我想显示 4 张图像,因此我使用 来unsigned short表示当前图像的索引。当我按A时,索引减1;当我按 D 时,索引增加 1。

image_index = (image_index - 1) % 4;我正在使用(以及 D 按键上的image_index = (image_index + 1) % 4;)计算 A 按键上的索引

如果我向前循环(即,按 D),一切都会按预期工作,但如果我位于索引 0 并按 A,它会下溢到无符号短整型的最大值,并且不会以 4 为模来给出索引3.

我知道对于有符号类型,上溢/下溢是 UB,但我确信对于无符号类型,它是定义良好的。有什么想法可能导致它忽略模数吗?

enum class Errors : short {
  kSdlSuccess = 0,
  kSdlInitFailure = -1,
  kSdlWindowCreationError = -2,
  kSdlRendererCreationError = -3
};

int main(int argc, char** argv) {

  sdl::Context ctx;
  sdl::Window window({ .w = 600, .h = 480, .flags = 0});
  sdl::Renderer renderer(window, {0}); …
Run Code Online (Sandbox Code Playgroud)

c++ modulo underflow undefined-behavior

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