无符号数和有符号数的“bug”

这篇具有很好参考价值的文章主要介绍了无符号数和有符号数的“bug”。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 起因

在实现kmp算法时,出现了诡异的现象,看下面的代码:

int KMP (const char *s, const char *t)
{
	int lenS = strlen (s);
	int lenT = strlen (t);
	
	int next[lenT];
	get_next (next, t);
	
	int i = 0;
	int j = 0;
	while (i < lenS && j < lenT) {
	
		if (j == -1 || s[i] == t[j]) {
			++i;
			++j;
		} else {
			j = next[j];
		}
	}
	if (j == strlen (t))
		return i - j;
	else
		return -1;
}

代码过程不重要。

乍一看lenSstrlen(s)是等价的,可是如果将lenS都替换成strlen(s)lenT都替换成strlen(t),就会得到非预期结果,??? 一脸问号

2. 发现问题

注意到strlen()返回的类型是size_t,有了一丝怀疑。
于是,改掉其中两行:

int lenS = strlen (s);
int lenT = strlen (t);
//	换成下面的
size_t lenS = strlen(s);
size_t lenT = strlen(t)

结果,代码果然不能正常工作了,拿gdb单步追踪,发现了问题所在:索引变量j的值可能为-1,此时 j为有符号负数,而size_t是无符号的,于是 -1 < strlen(t)这个条件就为false

3. 验证

换个更直观的demo:

#include <stdio.h>

int main (void)
{
	int a = -1;
	size_t b = 100;
	
	if (a < b) {
		puts ("a < b");
	} else {
		puts ("a > b");
	}
}

输出结果为a > b,与预期截然相反,总以为编译器会聪明地处理好这种情况,然而并没有。

从概率上来讲,这个错误是很容易犯的,而且不是很好查。然而居然头一次遇到,多少有些后怕。

看下这个demo的汇编代码:
无符号数和有符号数的“bug”,C语言,bug

可以看到,第 20行将-1赋值给%-4(rbp)(a),将100赋值给-16(%rbp)
(b),也就是我们定义的两个整型变量。

将a存入%eax,然后用ctlq(cdeq)指令将它符号位扩展至%rax(0xFFFFFFFFFFFFFFFF),最后用无符号比较指令jnb来进行条件判断。文章来源地址https://www.toymoban.com/news/detail-605573.html

到了这里,关于无符号数和有符号数的“bug”的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包