浅谈DEBUG版本与RELEASE版本

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/nszjh/article/details/35239307

DEBUG版本通常是项目处理调试阶段的一种过渡版本,它跟本地的环境变量设置相关,并且能进行调试(如单步、断点等),一般来说它是不经过优化的,所以运行速度上不占优势。而RELEASE版本为了速度上和代码大小上都会作出一定的优化,所以两者区别还是蛮大的。

下面以一个多线程程序为例来讲解两者的区别。

线程1:

UINT CTCP_viewDlg::ThreadTcpFun(LPVOID lpParam)
{
	CTCP_viewDlg *dlg = (CTCP_viewDlg *)lpParam;
	dlg->ReceiveTcpRun();
	return 0;
}

void CTCP_viewDlg::ReceiveTcpRun()
{
	while(1)
	{
		if(true == begin_rev)
		{
			Tcp_Receive();
		}
	}
}
void CTCP_viewDlg::RunTcpReceive()      //线程函数声明
{
	CWinThread* pThread;
	pThread = AfxBeginThread(ThreadTcpFun, (void *)this);
}



线程2:(按钮消息处理)

void CTCP_viewDlg::OnBnClickedConnect()
{
	// TODO: 在此添加控件通知处理程序代码

	CEdit* Ip = ((CEdit*)GetDlgItem(IDC_IP));
	Ip->GetWindowText(ip_addr);
	TcpInit(ip_addr);//初始化
	begin_rev = true;
	drawimage(image.GetImage(),IDC_IMAGE);    //绘出图像到工作区
}


bool begin_rev;      ///此变量定义为bool类型


当处理按钮的主线程触发,begin_rev变量被置为真,这里将使线程1执行Tcp_Receive()函数,而这个函数是用于接收TCP数据的,它是一个死循环一直在接收着。

在DEBUG版本上,以上代码是能正常运行的,而放在RELEASE版本上以上代码则不能正常运行,这是为什么呢?

因为在DEBUG版本上, begin_rev变量并没有被编译器进行优化,所以当按钮点击后,使其置为真后能让线程1“检查”出来,所以线程1可以正常的进入到接收函数里。而当程序被发行时,编译器会对代码进行优化,此时 begin_rev变量在线程1里


if(true == begin_rev)
{
	Tcp_Receive();
}

begin_rev变量被优化成只判断一次(在线程开始的时候),以后便不再判断此变量的真假,所以发行版本上Tcp_Receive()函数是不会被执行到的。

那么如何解决这个问题呢? 我们可以利用一个关键词volatile,这个关键词如何读者用过单片机会清楚,它被用于在中断处理程序里,让编译器不优化变量的,而此处它也同样适用,在声明变量前加入这个关键词便可将问题解决。

如果遇到程序在DEBUG版本上运行正常,而在发行版本运行不正常里,通常应该想到编译器优化这一点来,然后对代码进行查看,是否与以上所描述情况相近,如果是则可以参考这种做法来进行解决,这也是十分简便的做法。

展开阅读全文

没有更多推荐了,返回首页