假设我有以下C代码.
unsigned int u = 1234;
int i = -5678;
unsigned int result = u + i;
Run Code Online (Sandbox Code Playgroud)
什么隐式转换在这里怎么回事,这是代码为安全的所有值u和i?(安全,从某种意义上说,即使此示例中的结果会溢出到某个巨大的正数,我也可以将其转换回int并获得真实的结果.)
以下代码使运行时错误导致C++崩溃:
#include <string>
using namespace std;
int main() {
string s = "aa";
for (int i = 0; i < s.length() - 3; i++) {
}
}
Run Code Online (Sandbox Code Playgroud)
虽然此代码不会崩溃:
#include <string>
using namespace std;
int main() {
string s = "aa";
int len = s.length() - 3;
for (int i = 0; i < len; i++) {
}
}
Run Code Online (Sandbox Code Playgroud)
我只是不知道如何解释它.这种行为可能是什么原因?
是否有任何c ++标准段落表示使用-1此方法是可移植和正确的方法或正确执行此操作的唯一方法是使用预定义值?
我有一个谈话与我的同事,什么是更好的:使用-1最多的无符号整数,或者使用从价值limits.h还是std::numeric_limits?
我已经告诉我的同事,使用预定义的最大值,limits.h或者std::numeric_limits是这样做的便携和干净的方式,然而,同事反对-1像数字限制一样可移植,而且更多,它还有一个优点:
unsigned short i = -1; // unsigned short max
Run Code Online (Sandbox Code Playgroud)
可以轻松更改为任何其他类型,如
unsigned long i = -1; // unsigned long max
Run Code Online (Sandbox Code Playgroud)
当使用limits.h头文件中的预定义值时,或者std::numeric_limits还需要将其与左侧的类型一起重写.
码:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
using std::cerr;
using std::cout;
using std::stringstream;
using std::string;
using std::for_each;
void convert(const string& a_value)
{
unsigned short i;
if (stringstream(a_value) >> i)
cout << a_value << " converted to " << i << ".\n";
else
cerr << a_value << " failed to convert.\n";
}
int main()
{
string inputs[] = { "abc", "10", "999999999999999999999", "-10", "0" };
for_each(inputs, inputs + (sizeof(inputs)/sizeof(inputs[0])), convert);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Visual Studio Compiler的输出(v7,v8,v9,v10):
abc failed to …
我需要拿一个size_t volume并计算这个结果size_t:
size_t next = (volume * 8 + 3) / 5
Run Code Online (Sandbox Code Playgroud)
如果这个结果会溢出,size_t那么next应该为零.问题当然是volume * 8 + 3溢出,而整个结果适合于size_t.
目前我正在拆分最后4位volume并分别执行乘法,加法和除法.我的问题是:如果没有比这更大的类型,我能做得比目前为止做得更好size_t吗?
size_t next_volume(size_t volume) {
// check if the numerator will overflow size_t
if (volume > (SIZE_MAX - 3) / 8) {
size_t lower, upper;
// multiply lower 4 bits by 8 and add 3
lower = ((volume & 0xF) * 8) + 3;
// downshift …Run Code Online (Sandbox Code Playgroud) 如果我需要获取最大值,将-1分配给unsigned int或其他无符号c ++数据类型是否安全?
是否存在无法给出无符号数据类型可以包含的最高值的情况?
我在函数中有一些代码,它将使用递增/递减运算符更改/更新值.例如:
static void update_value(char op)
{
if (op == '+')
value++; // uint32_t global value
else
value--;
}
Run Code Online (Sandbox Code Playgroud)
该函数不会检查我们是否超过/低于最大/最小值.因此,当值为16时,调用者可以将其调用20次.结果为2 ^ 32 - 1 - 4.
我想提防,但我想使用标准库常量.我记得有一个size_t(或类似)变量代表uint32_t可以容纳的最大数字.
我不记得确切的常数和它们被定义的标题.有帮助吗?
我想进入SIZE_MAXC89.
我想到了以下方法SIZE_MAX:
const size_t SIZE_MAX = -1;
Run Code Online (Sandbox Code Playgroud)
由于标准(§6.2.1.2ANSIC)说:
当有符号整数转换为具有相等或更大大小的无符号整数时,如果有符号整数的值为非负,则其值不变.否则:如果无符号整数的大小更大,则有符号整数首先被提升为与无符号整数对应的有符号整数; 通过向该值添加一个大于可以在无符号整数类型 28中表示的最大数字的值,将该值转换为无符号
脚注28:
在二进制补码表示中,如果无符号整数具有更大的大小,则除了用符号位的副本填充高位以外,位模式中没有实际的变化.
这似乎已经定义了行为,但我不太确定我是否正确理解了该段落的措辞.
请注意,这个问题明确是关于C89的,所以这不能回答我的问题,因为标准有不同的措辞.
如果这不起作用,我提出的另一种方式是:
size_t get_size_max() {
static size_t max = 0;
if (max == 0) {
max -= 1U;
}
return max;
}
Run Code Online (Sandbox Code Playgroud)
但我在标准中找不到任何关于无符号整数下溢的信息,所以我在这里瞎了.
我在网站上看到了多个问题,这些问题解决了无符号整数上溢/下溢的问题。关于下溢的大多数问题都询问如何将负数分配给无符号整数。我不清楚的是,当unsigned int从另一个减去时会发生什么,unsigned int例如a - b结果为负。该标准的相关部分是:
涉及无符号操作数的计算永远不会溢出,因为无法用所得的无符号整数类型表示的结果的模数要比该所得类型可以表示的最大值大一模。
在这种情况下,您如何解释“减少”?这是否意味着UINT_MAX+1被添加到负的结果,直到它>= 0?
我看到这个问题解决了要点(基本上说标准选择谈论溢出,但是关于模数的要点也适用于下溢),但是我仍然不清楚:
说的结果a-b是-1; 根据标准,操作-1%(UINT_MAX+1)将返回-1(如解释在这里); 所以我们回到了起点。
这可能过于花哨,但这与C的计算模相反,此模是否意味着数学模?
以下证据表明:
inline
constexpr std::size_t prev(std::size_t i) {
--i;
return i;
}
int main() {
static const std::size_t i = 0;
static_assert(prev(i) == std::size_t(-1), "Decrementing should give std::size_t(-1)");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
那个快乐地汇编着-std=c++14.
我遇到了这个,因为我有一个循环索引,std::vector并想要向后循环,所以我把它改为
for (std::size_t i = std::min(idx, v.size() - 1); i != std::size_t(-1); --i) { ... }
Run Code Online (Sandbox Code Playgroud)
现在,我意识到我可以使用std::vector::reverse_iterator,但我现在的真正问题是,我期待定义的行为是什么?
是INT_MAX32位和64位环境之间有什么不同?虽然我听说有人说64位环境只使用32位环境的INT_MAX,但似乎情况确实如此.
#include <iostream>
#include <queue>
using namespace std;
int main()
{
// cout<<"Hello World";
priority_queue<int> spq; // max heap
priority_queue <int, vector<int>, greater<int>> lpq; // min heap
spq.push(1);
lpq.push(2);
lpq.push(3);
cout << spq.size() - lpq.size() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码给了我意想不到的非常大的价值18446744073709551615
我无法理解这里的问题。