编译中常见的一些错误解决方法
2015-03-28 10:16
253 查看
编译中常见的一些错误:
1、定义符在源码文件中的矛盾。
在C语言里,变量和函数的缺省状态是公用的。因此任何C源码的文件都可以引用存在于其他源码文件中的全局函数和全局变量,即使在这个源码文件中,并没有该全局函数或者全局变量的声明或者原型。因此你必须保证在你的全局函数或者全局变量没有重复的定义,否则在连接的时候会出现错误,可能在编译的时候也会提示告警。
解决方法:一种有效的解决方法,就是在你申明的全局函数或者全局变量名前,加入一个可以区分文件的前缀名:比如如果在gfx.c里的函数完全就可以加上前缀名gfx_。
如果要防止一个符号在它被定义的源文件以外看到,可以在它的定义前加上关键字“static", 则该关键字定义了该符号的局部属性,仅能在定义的文件内使用。(请注意,改关键字”static“的使用与局部变量定义时的区别)。
2、多次定义的符号。
当你用#include包含一个库文件的时候,实际上在编译的时候仅仅是在该处使用你包含的库文件逐字替换。如果头文件被#include到多个文档中时,该头文件中的所有定义都会在你引用的源代码中重新定义一次。重复定义,会导致链接出现错误。
解决方法:不要在头文件中定义变量。定义变量一般放到使用他们的源码问文件中,而在其他文件中声明一下就可以了。对于初学者来说,定义和声明,总是容易混淆。定义的时候,编译器会给该变量分配实际的内存空间,而声明,仅仅是通知编译器该变量存在,并且告知该变量的类型。声明一个变量的时候,需要在它的前面加上extern的关键字。
由于函数的原型中已经有了隐式的extern,所以不要考虑该问题。
3、重复定义、重复声明或者类型矛盾
考虑如果你的源码文件中#include了头文件a.h和b.h, 但是你的头文件中a.h又包含了b.h,则编译的时候会出现什么结果呢?很明显,b.h中定义的宏或者声明都会被执行两次。从理论上讲,这样的重复都是完全一样的拷贝,不会出现问题,但是在实际的编译中,这是不符合C的基本语法,可鞥编译的时候会出现错误,至少也是一个告警。
解决办法:确定每一个头文件中在任何一个源码文件中仅仅包含了一次。但是随着代码规模的扩大,通过认为控制的手段实在有点低效。聪明的方法是使用预处理器。
常用的用法是:
#ifndef MACRO_XXXX
#define MACRO_XXXX XXXX
#endif
但是如果每一个宏都这么放一条,是不是显得也太低效了呢?(还不说,我还真的看到了这么做的,呵呵!!)
在实际的应用中,我们只需在头文件的开头处定义:
#ifndef FILENAME_H
#define FILENAME_H
在库文件的最后处定义:
#endif
使用库文件的文档名代替上面的FILENAME就可以了
上述都是一些简单的技巧,其实在代码简单的时候,及时不使用上面的方法,也可以避免上述问题,但是当代码规模很庞大的时候,采用上述的一些技巧确实是一个良好的编程习惯,不过见人见智!!!
1、定义符在源码文件中的矛盾。
在C语言里,变量和函数的缺省状态是公用的。因此任何C源码的文件都可以引用存在于其他源码文件中的全局函数和全局变量,即使在这个源码文件中,并没有该全局函数或者全局变量的声明或者原型。因此你必须保证在你的全局函数或者全局变量没有重复的定义,否则在连接的时候会出现错误,可能在编译的时候也会提示告警。
解决方法:一种有效的解决方法,就是在你申明的全局函数或者全局变量名前,加入一个可以区分文件的前缀名:比如如果在gfx.c里的函数完全就可以加上前缀名gfx_。
如果要防止一个符号在它被定义的源文件以外看到,可以在它的定义前加上关键字“static", 则该关键字定义了该符号的局部属性,仅能在定义的文件内使用。(请注意,改关键字”static“的使用与局部变量定义时的区别)。
2、多次定义的符号。
当你用#include包含一个库文件的时候,实际上在编译的时候仅仅是在该处使用你包含的库文件逐字替换。如果头文件被#include到多个文档中时,该头文件中的所有定义都会在你引用的源代码中重新定义一次。重复定义,会导致链接出现错误。
解决方法:不要在头文件中定义变量。定义变量一般放到使用他们的源码问文件中,而在其他文件中声明一下就可以了。对于初学者来说,定义和声明,总是容易混淆。定义的时候,编译器会给该变量分配实际的内存空间,而声明,仅仅是通知编译器该变量存在,并且告知该变量的类型。声明一个变量的时候,需要在它的前面加上extern的关键字。
由于函数的原型中已经有了隐式的extern,所以不要考虑该问题。
3、重复定义、重复声明或者类型矛盾
考虑如果你的源码文件中#include了头文件a.h和b.h, 但是你的头文件中a.h又包含了b.h,则编译的时候会出现什么结果呢?很明显,b.h中定义的宏或者声明都会被执行两次。从理论上讲,这样的重复都是完全一样的拷贝,不会出现问题,但是在实际的编译中,这是不符合C的基本语法,可鞥编译的时候会出现错误,至少也是一个告警。
解决办法:确定每一个头文件中在任何一个源码文件中仅仅包含了一次。但是随着代码规模的扩大,通过认为控制的手段实在有点低效。聪明的方法是使用预处理器。
常用的用法是:
#ifndef MACRO_XXXX
#define MACRO_XXXX XXXX
#endif
但是如果每一个宏都这么放一条,是不是显得也太低效了呢?(还不说,我还真的看到了这么做的,呵呵!!)
在实际的应用中,我们只需在头文件的开头处定义:
#ifndef FILENAME_H
#define FILENAME_H
在库文件的最后处定义:
#endif
使用库文件的文档名代替上面的FILENAME就可以了
上述都是一些简单的技巧,其实在代码简单的时候,及时不使用上面的方法,也可以避免上述问题,但是当代码规模很庞大的时候,采用上述的一些技巧确实是一个良好的编程习惯,不过见人见智!!!
相关文章推荐
- VC中常见的一些编译链接错误的解决(1)
- uClinux 内核编译常见错误及解决方法(zt)
- 关于vc6.0中常见的因为工程设置project setting设置不对而造成连接错误的一些情况和解决方法(转)
- VC6.0常见编译错误及解决方法
- C++ 遇到的一些常见错误及解决方法
- VS2005的一个常见编译错误的解决方法
- Oracle数据库的网络连接配置以及一些常见错误信息解决方法
- VC中常见的一些编译链接错误的解决
- ASP.NET编译执行常见错误及解决方法汇总之一
- ASP.NET编译执行常见错误及解决方法汇总之二
- ASP.NET编译执行常见错误及解决方法汇总
- ASP.NET编译执行常见错误及解决方法汇总
- ASP.NET编译执行常见错误及解决方法汇总之三
- ASP.NET编译执行常见错误及解决方法汇总之四
- ASP.NET编译执行常见错误及解决方法汇总之五(终结篇)
- linux内核编译linux 内核编译常见错误及解决方法
- VC中常见的一些编译链接错误的解决
- nutch安装配置运行时,一些常见的错误与解决方法
- ASP.NET编译执行常见错误及解决方法汇总(转载)
- VC6.0的一些路径设置及常见错误Error spawning cl.exe的解决方法!