栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C/C++中的静态变量注意事项(很多人都会踩坑,甚至现在还不明白)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C/C++中的静态变量注意事项(很多人都会踩坑,甚至现在还不明白)

前言

C/C++中的静态变量,相信大多数人都用过,但你很可能用错了,包括你现在所在的项目中都可能埋着这个坑,不信我们往下看!

正文

我们先来看一段大家常写的代码,很简单,这段代码没啥坑:

#include 

int GetData()
{
	static int a = 0;
	return a++;
}

int main()
{
	for (int i = 0; i < 100; ++i)
	{
		printf("%dn", GetData());
	}
}

大家都清楚,静态变量只初始化一次,所以GetData调用了100次,打印的结果也是0-99,想必大家都很清楚 ,那请问GetData中初始化变量a的代码只会执行一次?是在哪个阶段初始静态局部变量a的?

想必大家都能回答上来,静态局部变量a的生命周期从程序运行开始就已经存在并初始化了的,并非是在GetData函数中初始化的,但又不完全对,我们看下一段代码:

#include 

int GetA()
{
	return 0;
}

int GetData()
{
	static int a = GetA();
	return a++;
}

int main()
{
	for (int i = 0; i < 100; ++i)
	{
		printf("%dn", GetData());
	}
}

看了这段代码,不知道大家有没有懵逼?问题来了,请问GetA函数会被调用几次?静态局部变量a是在什么时候初始化的?给大家5秒钟思考!

OK!静态局部变量无论如何都只会初始化一次,这是没有毛病的,但此时静态局部变量a是在第一次调用GetData函数的时候才被初始化的,与前一个例子用常量初始化静态变量并不相同,当然生命周期还是从程序运行开始到程序结束为止。

那编译器是怎么初始化静态变量a的呢?编译器会改造GetData方法如下:

int GetData()
{
	static bool init = false;
	if (!init)
	{
		a = GetA();//a已经被定义在全局了
		init = true;
	}
	return a++;
}

这样编译器就可以保证静态变量a在GetData函数内只被初始化一次,但请问a的初始化是否线程安全?

当然,不同编译器的实现并不相同,有的编译器会在初始化全局变量a的时候用上临界区等,以保证初始化的线程安全,有的却并没有,当然为了自己的代码兼容性更强,建议不要这样写,随便换个方法都能替代。或者只使用常量去初始化静态变量,这能保证线程安全!

总结,编译器在我们不知道的地方默默付出,大家要知道感恩!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025462.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号