我目前正在使用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) 我理解,对于隐式转换,如果我们有无符号类型操作数和带符号类型操作数,并且无符号操作数的类型与带符号操作数的类型相同(或更大),则将转换带符号操作数未签名.
所以:
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) 考虑以下:
#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
谢谢, …
我有以下功能:
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().
我想显示 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)