GCC常见错误解析.docx
- 文档编号:9979618
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:15
- 大小:22.89KB
GCC常见错误解析.docx
《GCC常见错误解析.docx》由会员分享,可在线阅读,更多相关《GCC常见错误解析.docx(15页珍藏版)》请在冰豆网上搜索。
GCC常见错误解析
GCC常见错误解析
一、错误类型
第一类∶C语法错误
错误信息∶文件source.c中第n行有语法错误(syntexerrror)。
这种类型的错误,一般都是C语言的语法错误,应该仔细检查源代码文件中第n行及该行之前的程序,有时也需要对该文件所包含的头文件进行检查。
有些情况下,一个很简单的语法错误,gcc会给出一大堆错误,此时要保持清醒的头脑,不要被其吓倒,必要的时候再参考一下C语言的基本教材。
第二类∶头文件错误
错误信息∶找不到头文件head.h(Cannotfindincludefilehead.h)。
这类错误是源代码文件中的包含头文件有问题,可能的原因有头文件名错误、指定的头文件所在目录名错误等,也可能是错误地使用了双引号和尖括号。
第三类∶档案库错误
错误信息∶连接程序找不到所需的函数库,例如∶ld:
-lm:
Nosuchfileordirectory.
这类错误是与目标文件相连接的函数库有错误,可能的原因是函数库名错误、指定的函数库所在目录名称错误等,检查的方法是使用find命令在可能的目录中寻找相应的函数库名,确定档案库及目录的名称并修改程序中及编译选项中的名称。
第四类∶未定义符号
错误信息∶有未定义的符号(Undefinedsymbol)。
这类错误是在连接过程中出现的,可能有两种原因∶一是使用者自己定义的函数或者全局变量所在源代码文件,没有被编译、连接,或者干脆还没有定义,这需要使用者根据实际情况修改源程序,给出全局变量或者函数的定义体;二是未定义的符号是一个标准的库函数,在源程序中使用了该库函数,而连接过程中还没有给定相应的函数库的名称,或者是该档案库的目录名称有问题,这时需要使用档案库维护命令ar检查我们需要的库函数到底位于哪一个函数库中,确定之后,修改gcc连接选项中的-l和-L项。
排除编译、连接过程中的错误,应该说这只是程序设计中最简单、最基本的一个步骤,可以说只是开了个头。
这个过程中的错误,只是我们在使用C语言描述一个算法中所产生的错误,是比较容易排除的。
我们写一个程序,到编译、连接通过为止,应该说刚刚开始,程序在运行过程中所出现的问题,是算法设计有问题,说得更玄点是对问题的认识和理解不够,还需要更加深入地测试、调试和修改。
一个程序,稍为复杂的程序,往往要经过多次的编译、连接和测试、修改。
二、常见错误信息解析与处理
1、预处理时的错误信息
Nosuchfileordirectory
中文含义:
没有相应文件或目录
错误原因:
编译器的搜索路径上找不到所需要的文件。
该文件可能已在命令行中指定,或在#include语句中说明。
处理方法:
查看文件名是否正确,或文件所存放的目录是否已添加到系统目录或链接目录中。
以下是样例:
#include
文件名不正确*/
intmain(void){
printf("HelloWorld!
\n");
return0;
}
上面的程序试图引入一个不存在的文件‘stdoi.h’,这就会引发如下错误:
‘stdoi.h:
Nosuchfileordirectory’。
而正确的文件名应该是‘stdio.h’。
macroor'#include'recursiontoodeep
中文含义:
宏或'#include'递归太深
错误原因:
语句#include嵌套太深。
当预处理器遇到太多嵌套的#include指令时,会导致此错误。
通常该错误由两个或多个文件进行相互引用时,会引发无限递归。
如:
/*foo.h*/
#include"bar.h"
...
/*bar.h*/
#include"foo.h"
...
解决方法是确保各文件没有互相引用。
invalidpreprocessingdirective#...
中文含义:
非法的预处理命令#...
错误原因:
该错误指明预处理器遇到了不可识别的#命令。
如:
#ifFOO
intx=1;
#elseifBAR/*应写成#elif*/
intx=2;
#else
intx=3;
#endif
预处理器语法在#if块中需要#elif而不是"elseif"条件,也不是#elseif。
warning:
Thisfileincludesatleastonedeprecatedorantiquatedheader.
中文含义:
警告:
文件中至少引用了一个已废弃的或过时的头文件
错误原因:
该错误通常是在C++程序中引用了旧式的头文件库,如’iostream.h’,在现代C++库头文件没有’.h’扩展名。
旧头文件导入其函数到顶层全局名字空间,对C++需要使用std:
:
名字空间。
当然,对旧式风格的头文件仍然支持,所以对现有程序会继续编译,只是给出警告。
如:
#include
intmain(void){
cout<<"HelloWorld!
\n";
return0;
}
‘iostream.h’应改写为#include
:
cout。
unterminated'#if'conditional
中文含义:
'#if'语句条件没有终止
错误原因:
缺少#endif语句
2、编译时的错误信息
'variable'undeclared(firstuseinthisfunction)
中文含义:
变量'variable'没有声明(第一次使用此变量)
解决方法:
在使用前声明该变量。
解析:
在C和C++中,变量必须先声明后使用。
如:
intmain(void){
inti;
j=0;/*j变量没声明*/
returnj;
}
此例中,j是没经声明的变量,所以将触发错误:
'j'undeclared.
parseerrorbefore'...'
中文含义:
在'XXX'语句前解析错误
错误原因:
语法错误
解析:
通常是编译器遇到了未期望的输入。
如:
不合语法的字符串序列。
此错误也可能因为丢失花括号、园括号或分号,或写了非法的保留字而引发。
#include
intmain(void){
printf("Hello")/*丢失分号*/
printf("World!
\n");
return0;
}
conflictingtypesfor'Alex'
中文含义:
对'Alex'变量存在突出类型
错误原因:
前面可能已对'Alex'声明了其它数据类型。
例如:
存在两条语句分别声明了两次'Alex'变量为两种枚举(enum)类型。
twoormoredatatypesindeclarationspecifiers
中文含义:
在声明标识符中存在多种数据类型
最容易出现这样的错误,原因是在程序里少了个“;”号。
有可能在头文件里,也有可能在本文件中(最容易出错的是在结构体中忘了“;”)。
toomanytypesindeclaration
中文含义:
在声明中定义太多的类型
1.是否多次包含着个头文件?
检查一下例如:
#ifndefTConfigH
#defineTConfigH
#endif//是否少了这个
2.看下将长语句分为多行时,与下一行语句间是否少了逻辑运算符关系,关系运算符之类的符号
warning:
comparisonbetweenpointerandinteger
中文含义:
警告:
对指针和整型值进行比较
可能没问题。
此警告通常是由'if(strstr(line,"word")!
=NULL)'之类的strstr函数返回指针或空值。
subscriptedvalueisneitherarraynorpointer
中文含义:
下标值不符合数组或指针要求
错误原因:
企图使用可变的变量作为下标
floppyto.c:
782:
parseerroratendofinput
中文含义:
在文件尾部解析错误
floppyto.c是程序文件名,782是错误行数,但该数字大于文件长度。
错误原因:
存在没配对的花括号{}或注解/**/
#include
intmain(void){
if
(1){
printf("HelloWorld!
\n");
return0;/*花括号不匹配*/
}
parseerrorbefore'printf'
中文含义:
在'printf'之前解析错误
错误原因:
在该语句之前缺少分号';'
warning:
implicitdeclarationoffunction'...'
中文含义:
警告:
与函数XXX的隐式声明不相符
错误原因:
该错误是因为使用的函数没有原型声明而产生。
产生的因为可以是导入错误的头文件,或忘记提供函数原型。
如:
intmain(void){
printf("HelloWorld!
\n");/*没有头文件*/
return0;
}
程序中没有导入系统头文件’stdio.h’,所以也就不存在printf的原型声明。
改正方法:
在程序最前面加入一行语句:
#include
unterminatedstringorcharacterconstant
中文含义:
未终止的字符串或字符常量
错误原因:
该错误是因为使用字符串或字符常量缺少配对的引号而产生。
对字符而言,应使用成对的单引号,而对字符串,应使用成对的双引号。
#include
intmain(void){
printf("HelloWorld!
\n);/*缺少闭双引号*/
return0;
}
characterconstanttoolong
中文含义:
字符常量太长
错误原因:
在C和C++中,字符常量是由单引号封装起来的单个字符,并且有相应的ASCII值。
如'a'对应的ASCII为67,而'\n'对应的ASCII为10。
本错误是因为使用单引号封装了多于一个字符而引发。
如:
#include
intmain(void){
printf('HelloWorld!
\n');/*错误的封装*/
return0;
}
多字符组成的是字符串,应用双引号封装。
对上例,应改写成:
"HelloWorld!
"。
warning:
initializationmakesintegerfrompointerwithoutacast
中文含义:
警告:
初始化过程中不能从指针到整型数进行转换
错误原因:
该错误指示在整型数环境中误用了指针。
从技术上,可以在指针和整型数之间相互转换,但这很少用在外部系统级应用程序中。
通常,此类警告是在使用了指针而没有释放该指针而引发。
(如语句写成inti=p而不是inti=*p,其中p是指针)。
该警告在类型char和char*之间转换时也可能引发,因为char也是整数类型。
intmain(void){
charc="\n";/*不正确*/
return0;
}
变量c是char类型,而"\n"是字符串且会被系统认为是constchar*指针(将占用2-字节内存,包括'\0',因为字符串没有终止符)。
类似的错误也会发生在对宏NULL的误用:
#include
intmain(void){
inti=NULL;/*不正确*/
return0;
}
在C的‘stdlib.h’中,宏NULL被定义为((void*)0),它只能用在指针环境中。
dereferencingpointertoincompletetype
中文含义:
间接引用指针为不合适的类型
错误原因:
程序试图通过指针访问一个没有事先声明的结构体内元素。
在C和C++中,在声明指向结构的指针时,应先声明结构体。
structbtree*data;
intmain(void){
data->size=0;/*不合适的类型*/
return0;
}
此程序使用btree结构data的前向声明。
然而,在指针间接独立访问内存前,需要定义该结构。
warning:
unknownescapesequence'...'
中文含义:
警告:
未知的转义序列
错误原因:
使用了不正确的转义字符。
合法的转义字符序列如下:
\n新行
\t制表符
\b回退
\r回车
\f换页
\v垂直制表
\a警告(铃声)
组合字符\\,\',\"和\?
表示相应的独立字符。
转义序列也可用八进制码\0--\377和十六进制码\0x00--\0xFF来表示。
#include
intmain(void){
printf("HELLOWORLD!
\N");/*\N错误*/
return0;
}
warning:
suggestparenthesesaroundassignmentusedastruthvalue
中文含义:
警告:
建议用圆括号括上用于逻辑值的赋值表达式
错误原因:
该警告强调潜在的语义错误,程序在条件语句或其它逻辑表达式测试中使用了赋值操作符‘=’而不是比较操作符‘==’。
当然在语法上,赋值操作符可作为逻辑值使用,但在实践中很少用。
#include
intmain(void){
inti=0;
if(i=1){/*=应该是==*/
printf("unexpectedresult\n");
}
return0;
}
warning:
controlreachesendofnon-voidfunction
中文含义:
警告:
控制到达非void函数末端。
错误原因:
若一个函数已声明为有返回数据类型(如int或double),那么就必须在函数中的适当位置(所有可能的结束点)使用return语句返回相应类型的值。
否则,就属于不是良好定义的函数。
若函数声明为void,则不需要return语句。
#include
intdisplay(constchar*str){
printf("%s\n",str);
}
以上程序在display函数的尾部没有返回语句,但它又声明为返回int类型。
可以通过添加return0;之类的语句加以解决。
当使用gcc时,C程序中的main函数必须返回一个int型数据(用于表明程序的退出状态)。
warning:
unusedvariable'...'
中文含义:
警告:
存在从未使用的变量XXX。
warning:
unusedparameter'...'
中文含义:
警告:
存在从未使用的参数XXX。
错误原因:
该警告指示存在已声明为局部的变量或函数参数,但在其它地方并没使用过它。
没使用过的变量可能会导致程序性错误,如偶尔在预期的位置上写了不同的变量名。
intfoo(intk,char*p){
inti,j;
j=k;
returnj;
}
在本程序中,变量i和参数p从没使用过。
warning:
passingargof...as...duetoprototype
中文含义:
警告:
传送XX参数为XXX,但原型不匹配。
错误原因:
该警告指示在调用函数时,存在与声明的参数类型原型不一致的情况。
warning:
passingarg1of'cpystr'makesintegerfrompointer
中文含义:
警告:
函数的参数1存在参数不匹配,即无法进行类型转换
错误原因:
类型转换不匹配
下面的样例就存在这方面的问题:
voidcpystr(charitem);
main(){
charsrc[]="martinleslie";
cpystr(src);
}
cpystr(charitem){}
函数应该写成如下类似的格式:
voidcpystr(charitem[]);
main(){
charsrc[]="martinleslie";
cpystr(src);
}
cpystr(charitem[]){}
warning:
assignmentofread-onlylocation
中文含义:
警告:
对只读变量进行赋值。
错误原因:
检查赋值的变量是否已用const修饰或已被声明为常量。
warning:
castdiscardsqualifiersfrompointertargettype
中文含义:
警告:
在指针目标类型中存在不合适的转换限定符。
warning:
assignmentdiscardsqualifiers...
中文含义:
警告:
赋值丢弃限定符XXX。
warning:
initializationdiscardsqualifiers...
中文含义:
警告:
初始化丢弃限定符XXX。
warning:
returndiscardsqualifiers...
中文含义:
警告:
返回值丢弃限定符XXX。
错误原因:
对指针的不正确使用了违法的限定符。
检查赋值的变量是否已用const修饰或已被声明为常量。
若指针被限制为const则该指针不能被修改,且只能被用于向其它指针赋值。
char*f(constchar*s){
*s='\0';/*向只读数据赋值*/
returns;/*将会丢弃常量,即并不能被返回*/
}
该程序试图修改常量数据,并在返回值中使用常量属性参数而导致丢弃。
initializerelementisnotaconstant
中文含义:
初始化元素不是常量。
错误原因:
在C中,全局变量只能在初始化是赋值常量,如数值、NULL或字符串常量。
若使用了非常量值则会引发此错误。
#include
FILE*stream=stdout;/*不是常量*/
inti=10;
intj=2*i;/*不是常量*/
intmain(void){
fprintf(stream,"HelloWorld!
\n");
return0;
}
注意:
在C++中则允许在初始化中使用非常量数据。
3、链接时的错误信息
filenotrecognized:
Fileformatnotrecognized
中文含义:
文件不可识别:
文件格式不可识别。
错误原因:
文件扩展名不是‘.c’。
#include
intmain(void){
printf("HelloWorld!
\n");
return0;
}
若上述文件保存为‘hello’但没有扩展名,则编译时会给出如下错误:
$gcc-Wallhello
hello:
filenotrecognized:
Fileformatnot
recognized
collect2:
ldreturned1exitstatus
解决方案是将文件重命名为带合适的扩展名。
对本例可重命名为‘hello.c’.
undefinedreferenceto'foo'
collect2:
ldreturned1exitstatus
中文含义:
没定义对'foo'的引用。
错误原因:
程序中使用了在本文件和其它库中没有定义的函数或变量。
有可能是丢失了链接库,或使用了不正确的名字。
在此例中,’collect2’是链接程序的一部分。
intfoo(void);
intmain(void){
foo();
return0;
}
/usr/lib/crt1.o(.text+0x18):
undefinedreferenceto'main'
中文含义:
没定义对main函数的引用
错误原因:
程序中缺少main()函数。
/usr/lib/crt0.o:
Undefinedsymbol_mainreferencedfromtextsegment
中文含义:
从文本段引用没定义的_main符号
错误原因:
缺少main()函数—但实际上有,为什么?
1.在头文件中可能存在语法错误;
2.在C源文件中可能缺少gcc命令
Undefinedsymbol_initscrreferencedfromtextsegment
中文含义:
从文本段引用没定义的_initscr符号
错误原因:
调用了一个函数,但并没有该函数,或在#include语句中没有包含该函数的库。
4、运行时的错误信息
errorwhileloadingsharedlibraries:
cannotopensharedobjectfile:
Nosuchfileordirectory
中文含义:
装载共享库是出错:
不能打开共享对象文件:
不存在该文件或目录
错误原因:
程序中使用了共享库,但程序启动时通过动态链接找不到所需的共享库文件。
如果确定存在,则请修改共享类库搜索路径变量值LD_LIBRARY_PATH。
Segmentationfault
中文含义:
分段错误,总线错误
错误原因:
企图访问受保护的内容或覆盖重要的数据!
它指明内存访问错误。
通常的原因如下:
1、反向引用一个空指针或没初始化的指针;
2、超出数组访问的下标;
3、对malloc,free和相关函数不正确的使用;
4、使用scanf时的参数(数量、类型)不正确。
floatingpointexception
中文含义:
浮点运算异常
错误原因:
这是个算术运算异常。
如除数为0,上溢、下溢或非法的操作(如对-1求平方根)。
Illegalinstruction
中文含义:
非法指令
错误原因:
当系统遇到非法的机器指令时,产生此错误。
通常此类错误是在源代码已编译成特定机器的目标代码后,又在其它类型的机器上运行时发生。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- GCC 常见 错误 解析