编写安全代码:不要在头文件中定义变量
2015-05-14 10:36
302 查看
作者:gfree.wind@gmail.com
博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
微博:weibo.com/glinuxer
QQ技术群:4367710
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
==========================================================================================================================================================
今天这个主题很简单。但是这么一个初级问题,居然真正发生在我的周围。
前几天帮助同事检查一个问题。他这样描述该现象:他定义了一个全局变量,然后调用一个函数F修改了该全局变量,但是退出函数时该全局变量的值又被改了。我到他的调试环境中,先查看了一下现象。问题重现了。—— 我一直认为,所有能够重现的问题都不是问题。只要能够重现,就一定可以修正。
对于这一问题,我的第一反应是竞争引起的。于是我首先使用GDB的set scheduler-locking on,保证其它线程处于停止状态,避免竞争。又试了一次,问题还是存在。在函数退出的时候,打印了一下当时的值。然后退出,再次打印,发现其值变为了初始值。感觉确实有点奇怪。于是看了看他的代码,一看该全局变量定义在头文件中static
int g_variable = 0。看到这里,尽管我不知道其它代码是怎么写的。我就想到了问题的原因。这里的全局变量g_variable肯定有两份。函数F和调用者一定在不同的文件中,它们都include了这个头文件。结果在函数F中修改了一个g_variable,而调用者中使用和查看的是另一个g_variable。解决方法是,去一个c文件中定义这个全局变量,然后到头文件中声明。
虽然我很快的解决了这个问题。但是我却想,这个问题真的是一个很初级的问题。而我这位同事已经是一名senior的开发人员了。为什么还会犯这种错误呢?这里我对事不对人。主要的原因还是对于编程的基础没有理解。头文件中不要定义全局变量,看似是一条死的规则。其实只要真正领会什么是头文件,头文件是如何include到.c源文件中的。这条规则根本不需要记忆,而是一种理解。这样会自然的就会写出正确的代码,而不会犯这样的错误。
说到这里,简单说一下头文件的知识。头文件的作用,主要是用于声明变量,函数等等,然后可以被多个源文件引用。其实我认为其根本目的,一是为了代码的整齐,更重要是为了消除重复的代码。因为多个源文件都要相同的声明,这时就可以用一行include 头文件来解决。而include,在预编译阶段,实际上是将头文件中所有的代码都插入到include的位置。真正理解了这个过程,肯定不会犯本文中的这个错误。
博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
微博:weibo.com/glinuxer
QQ技术群:4367710
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
==========================================================================================================================================================
今天这个主题很简单。但是这么一个初级问题,居然真正发生在我的周围。
前几天帮助同事检查一个问题。他这样描述该现象:他定义了一个全局变量,然后调用一个函数F修改了该全局变量,但是退出函数时该全局变量的值又被改了。我到他的调试环境中,先查看了一下现象。问题重现了。—— 我一直认为,所有能够重现的问题都不是问题。只要能够重现,就一定可以修正。
对于这一问题,我的第一反应是竞争引起的。于是我首先使用GDB的set scheduler-locking on,保证其它线程处于停止状态,避免竞争。又试了一次,问题还是存在。在函数退出的时候,打印了一下当时的值。然后退出,再次打印,发现其值变为了初始值。感觉确实有点奇怪。于是看了看他的代码,一看该全局变量定义在头文件中static
int g_variable = 0。看到这里,尽管我不知道其它代码是怎么写的。我就想到了问题的原因。这里的全局变量g_variable肯定有两份。函数F和调用者一定在不同的文件中,它们都include了这个头文件。结果在函数F中修改了一个g_variable,而调用者中使用和查看的是另一个g_variable。解决方法是,去一个c文件中定义这个全局变量,然后到头文件中声明。
虽然我很快的解决了这个问题。但是我却想,这个问题真的是一个很初级的问题。而我这位同事已经是一名senior的开发人员了。为什么还会犯这种错误呢?这里我对事不对人。主要的原因还是对于编程的基础没有理解。头文件中不要定义全局变量,看似是一条死的规则。其实只要真正领会什么是头文件,头文件是如何include到.c源文件中的。这条规则根本不需要记忆,而是一种理解。这样会自然的就会写出正确的代码,而不会犯这样的错误。
说到这里,简单说一下头文件的知识。头文件的作用,主要是用于声明变量,函数等等,然后可以被多个源文件引用。其实我认为其根本目的,一是为了代码的整齐,更重要是为了消除重复的代码。因为多个源文件都要相同的声明,这时就可以用一行include 头文件来解决。而include,在预编译阶段,实际上是将头文件中所有的代码都插入到include的位置。真正理解了这个过程,肯定不会犯本文中的这个错误。
相关文章推荐
- 编写安全代码:不要在头文件中定义变量
- 编写安全代码——不要用memcmp比较structure
- 编写安全代码——不要用memcmp比较structure
- 变量一般不要定义在.h文件中
- 头文件中不要去定义函数与变量
- c++ 变量不要定义在.h 头文件当中(main already defined in *.obj 解决方法)
- C语言中尽量不要在头文件中定义变量
- 转载 永远不要在.h文件中定义变量!
- 编写安全代码——不要用memcmp比较structure
- 编写安全代码——不要用memcmp比较structure
- VBA处理文件框架代码 【第二部分:变量定义】
- 不要在头文件中定义变量
- 变量一般不要定义在.h文件中
- 永远不要在.h文件中定义变量----->转载一篇博客
- 变量一般不要定义在.h文件中
- !!无须定义配置文件中的每个变量的读写操作,以下代码遍历界面中各个c#控件,自动记录其文本,作为配置文件保存
- 【自我修养】不要嘻嘻哈哈的在头文件中定义变量
- 编写自己的代码生成工具一:介绍及定义配置文件
- 编写安全代码——不要用memcmp比较structure
- 最好不要在头文件里面包含定义变量