分页: 1 / 1

GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 10:05
youqika
最近在看数据结构与算法的书,写了如下插入排序的程序,gcc4.3.3用I、III没有问题,II则得不到正确的结果,而vc6都没有问题
大神指点 :em70
$gcc -Wall filename.c
I、III输出:45,47,50,56
II输出:45,47,0,50

代码: 全选

#include <stdio.h>

typedef	unsigned char	bool;
#define	true	1
#define	false	(!true)

static  int insert_sort(int* p_arr, int count);

/*
 *插入排序,成功返回0
 */
int insert_sort(int* p_arr, int count)
{
	int res = -1, i = 1;
	int s = 0, e = 0, m = (s+e) >> 1;
	bool incm = false;	/*include m*/

	if(NULL == p_arr || count < 0)
		goto END;

	for(i = 1; i < count; ++i) {
		int ec = 0;	/*exchange time*/
		int j = i;

		s = 0;
		e = j-1;

		while (!(s > e)) {
			if (s == e) {
				incm = p_arr[j] < p_arr[m];
				break;
			} else {	/*s<e*/
				if (p_arr[j] < p_arr[m])
					e = m-1, m = (s+e) >> 1;
				else
					s = m+1, m = (s+e) >> 1;
			}
		}

		/*exchange*/
		for (ec = (incm ? j-m : j-m-1); \
				ec > 0; --ec, --j) {
I

代码: 全选

p_arr[j] ^= p_arr[j-1];
			p_arr[j-1] ^= p_arr[j];
			p_arr[j] ^= p_arr[j-1];
II

代码: 全选

p_arr[j] ^= p_arr[j-1] ^= p_arr[j] ^= p_arr[j-1];
III

代码: 全选

int tmp = p_arr[j];
			p_arr[j] = p_arr[j-1];
			p_arr[j-1] = tmp;

代码: 全选

}
	}
	res = 0;

END:
	return res;
}

#define DLC	4

int main(void)
{
	int i = 0;
	int x[DLC] = {45, 56, 47, 50};
	insert_sort(x, DLC);
	for (i = 0; i < DLC; ++i) {
		printf("%d;", x[i]);
	}
	printf("\n");
	return 0;
}

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 10:44
youqika
nobody knows ? :em20

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 11:16
youqika
算了,就用I吧,也清晰一点 :em37

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 17:00
kiddult
看着好头晕啊,楼主移位是干什么的?? :em20

赋值语句最好分开写,否则很容易出问题

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 17:21
BigSnake.NET
手头没有 gcc 4.3.3

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 18:37
youqika
kiddult 写了:看着好头晕啊,楼主移位是干什么的?? :em20
移位是除2,听说这样效率会高一些 :em06
kiddult 写了:赋值语句最好分开写,否则很容易出问题
貌似是的哦,gcc就出问题了,vc6就没问题 :em20 ,不知道gcc别的版本怎么样

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 18:40
youqika
注释有点少了,s是start,e是end,m是middle,j是i的替代品,防止i被无意间修改 :em06
不过这些都不是关键,关键是连赋值,难道这种写法不提倡了还是会出问题,抑或是可读性不好?

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 19:56
sarrow
同疑惑。

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 23:31
wyapples

代码: 全选

#include <stdio.h>

int main(int argc, char** argv)
{
	int a,b;
	a = 5;
	b = 10;
	
	a ^= b ^= a ^= b;
	
	printf("%d\t%d",a,b);
	
	return 0;
}
验证了一下,gcc会给警告,但是不会报错,运行正常。

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-13 23:42
BigSnake.NET
wyapples 写了:

代码: 全选

#include <stdio.h>

int main(int argc, char** argv)
{
	int a,b;
	a = 5;
	b = 10;
	
	a ^= b ^= a ^= b;
	
	printf("%d\t%d",a,b);
	
	return 0;
}
验证了一下,gcc会给警告,但是不会报错,运行正常。
应该是这样的
简化版

a ^= a ^= b;

发生了这几件事
1. a ^ b
2. 1 的结果赋给 a
3. a ^ 1 的结果
4. 3 的结果赋给 a

2, 3 在 1 后发生
4 在 3 后发生

2 与 3
2 与 4 不确定了

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-14 8:04
youqika
BigSnake.NET 写了:
wyapples 写了:

代码: 全选

#include <stdio.h>

int main(int argc, char** argv)
{
	int a,b;
	a = 5;
	b = 10;
	
	a ^= b ^= a ^= b;
	
	printf("%d\t%d",a,b);
	
	return 0;
}
验证了一下,gcc会给警告,但是不会报错,运行正常。
应该是这样的
简化版

a ^= a ^= b;

发生了这几件事
1. a ^ b
2. 1 的结果赋给 a
3. a ^ 1 的结果
4. 3 的结果赋给 a

2, 3 在 1 后发生
4 在 3 后发生

2 与 3
2 与 4 不确定了
我的目的是将a,b交换,“a ^= a ^= b;”这样不行吧 :em20
大家可以运行一下我的代码,应该就能看到错误了,话说回来,这确实不是什么大不了的问题
wyapples 写了:

代码: 全选

#include <stdio.h>

int main(int argc, char** argv)
{
	int a,b;
	a = 5;
	b = 10;
	
	a ^= b ^= a ^= b;
	
	printf("%d\t%d",a,b);
	
	return 0;
}
验证了一下,gcc会给警告,但是不会报错,运行正常。
既然gcc会给出警告,估计是这种写法已经过时了,大家还是不用的好 :em06

Re: GCC4.3.3有BUG???VC6则没问题

发表于 : 2009-09-14 12:53
BigSnake.NET
我说的是简化版... 四个变量同理, 不过情况数更多, 更复杂