在这个问题中,主题是如何使VS检查C#中的算术溢出并抛出异常:C#溢出不起作用?如何启用溢出检查?
其中一条评论说得有些奇怪,而且投票很多,我希望你能在这里帮助我:
您还可以使用checked关键字来包装语句或一组语句,以便显式检查它们是否存在算术溢出.设置项目范围的属性有点冒险,因为溢出通常是一个相当合理的期望.
我不太了解硬件,但我知道溢出与寄存器的工作方式有关.我一直认为溢出导致未定义的行为,应尽可能防止溢出.(在"正常"项目中,不编写恶意代码)
你怎么可能会想到一个溢出发生,为什么你不总是阻止它,如果你有可能性?(通过设置相应的编译器选项)
通过"非空",我的意思是在这个问题中包含至少一个非零字符的字符串.
作为参考,这是hashCode实现:
1493 public int hashCode() {
1494 int h = hash;
1495 if (h == 0) {
1496 int off = offset;
1497 char val[] = value;
1498 int len = count;
1499
1500 for (int i = 0; i < len; i++) {
1501 h = 31*h + val[off++];
1502 }
1503 hash = h;
1504 }
1505 return h;
1506 }
Run Code Online (Sandbox Code Playgroud)
并且算法在文档中指定.
在发生整数溢出之前,答案很简单:它不是.但我想知道的是,由于整数溢出,非空字符串的哈希码是否可能为零?你能建一个吗?
我正在寻找的理想情况是数学演示(或链接到一个)或构造算法.
如果 C 程序有未定义的行为,任何事情都可能发生。因此编译器可能会假设任何给定的程序不包含 UB。因此,假设我们的程序包含以下内容:
\nx += 5;\n/* Do something else without x in the meantime. */ \nx += 7;\nRun Code Online (Sandbox Code Playgroud)\n当然,这可以优化为
\n/* Do something without x. */\nx += 12;\nRun Code Online (Sandbox Code Playgroud)\n或类似的其他方式。
\n如果 x 具有类型,unsigned int则上述程序中不可能出现 UB。另一方面,如果 x 有类型signed int,则有可能溢出,从而产生 UB。由于编译器可能会假设我们的程序不包含UB,因此我们可以进行与上面相同的优化。事实上,在这种情况下,编译器甚至可以假设x - 12 <= MAX_INT.
然而,这似乎与 Jens Gustedt 著名的“Modern C”(第 42 页)相矛盾:
\n\n\n但这样的优化也可以被禁止,因为编译器无法证明某个操作不会强制程序终止。在我们的示例中,很大程度上取决于 x 的类型。如果 x 的当前值可能接近类型的上限,则看似无辜的操作 x += 7 可能会产生溢出。此类溢出根据类型的不同而有不同的处理方式。正如我们所看到的,无符号类型的溢出不是问题,并且压缩运算的结果将始终与两个单独的结果一致。对于其他类型,例如有符号整数类型(signed)和浮点类型(double),溢出可能会引发异常并终止程序。在这种情况下,无法执行优化。
\n
(强调我的)。如果编译器可以(并且确实)假设我们的程序没有 UB,为什么不能执行此优化?
\n …c optimization integer-overflow compiler-optimization undefined-behavior
我只是想知道灾难性的整数溢出是多么的真实.采用以下示例程序:
#include <iostream>
int main()
{
int a = 46341;
int b = a * a;
std::cout << "hello world\n";
}
Run Code Online (Sandbox Code Playgroud)
由于a * a32位平台上的溢出和整数溢出触发了未定义的行为,我是否有任何hello world实际出现在屏幕上的保证?
我根据以下标准引文从我的问题中删除了"已签名"部分:
(§5/ 5 C++ 03,§5/ 4 C++ 11)如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义.
(§3.9.1/ 4)声明的无符号整数
unsigned应遵守算术模2 ^ n的定律,其中n是该特定整数大小的值表示中的位数.这意味着无符号算术不会溢出,因为无法由结果无符号整数类型表示的结果以比模式生成的无符号整数类型所表示的最大值大1的数量为模.
有没有人详细解释如何利用整数?我已经阅读了很多关于这个概念的内容,我理解它是什么,我理解缓冲区溢出,但我不明白如何可靠地修改内存,或者以修改应用程序流的方式,通过使一个大于它定义的记忆....
我做了一个简单的程序,用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和C++没有提供一组实现提供的操作来执行提供溢出检查的每个基本整数操作(例如a bool safeAdd(int *out, int a, int b)).
据我所知,大多数指令集都有办法判断操作是否溢出(例如x86溢出和进位标志),并且在有符号整数的情况下也会发生定义.
因此,编译器是否应该能够做得更好,创建更简单,更快速的操作,而不是用C和C++编写代码?
我想将两个数相乘,并检测是否有溢出.最简单的方法是什么?
fn main() {
let num: u8 = 255;
let num2: u8 = num + 1;
println!("{}, {}", num, num2);
}
Run Code Online (Sandbox Code Playgroud)
当 时$ cargo build --release,这段代码不会产生编译错误。并且$ cargo run,产生运行时错误。
线程“main”因“尝试添加溢出”而惊慌失措,src/main.rs:3:20 注意:使用
RUST_BACKTRACE=1环境变量运行以显示回溯
这没关系。但我不明白的是下面的情况。当我删除 println 行时,会出现编译错误。
fn main() {
let num: u8 = 255;
let num2: u8 = num + 1;
}
Run Code Online (Sandbox Code Playgroud)
$ cargo build --release
error: this arithmetic operation will overflow
--> src/main.rs:3:20
|
3 | let num2: u8 = num + 1;
| ^^^^^^^ attempt to …Run Code Online (Sandbox Code Playgroud)