C语⾔编译警告和报错整理-持续更新
本帖总结编译出现的各种warnning和error的原因,持续更新。对本帖中出现的⽰例函数作个简单的说明:
1. char* get_char_pointer() : 返回⼀个char*类型。
2. int poiner_func(char* p):接收char* 类型的指针。
下⾯开始记录各种编译警告和错误
1. 警告:pointless comparison of unsigned integer with a negative constant
⼤意为:⼀个⽆意义的⽐较⽆符号整型和⼀个负数常量。
调⽤者:uint8 len; if(len < -1){return;} ⽐较正数⼩于-1 毫⽆意义。
2. 警告:implicit declaration of function ‘xxxxxxx’
代表隐式声明函数,出现在.c⽂件没有包含对应函数的.h⽂件就直接调⽤了那个函数,或者直接调⽤了在.c⾥实现的函数,没有在头⽂件⾥声明。这种不加头⽂件的情况要严令禁⽌。
3. 警告: assignment makes pointer from integer without a cast [-Wint-conversion]
出现这个警告的原因是在使⽤函数之前没有对函数进⾏声明,未经声明的函数原型⼀律默认为返回int值。这样,就相当于你调⽤了返回值为int的函数,并将其赋给了char*、int*等等指针变量,就会出现警告。
4. 警告: argument to ‘sizeof’ in ‘memset’ call is the same expression as the destination; did you mean to
dereference it? [-Wsizeof-pointer-memaccess]
sizeof 指针直译过来就是:“ memset”调⽤中“ sizeof”的参数与⽬标的表达式相同; 您是要取消引⽤它吗?⽬标表达式指的就是memset第⼀个参数,也就是指针,很明显提⽰sizeof也传⼊了变量指针,应该传⼊类型说明符和表达式。
调⽤者:char *str = get_char_pointer(); memset(str, 0, sizeof(str));就会出现警告。
5. 警告: initialization makes integer from pointer without a cast [-Wint-conversion]
调⽤者:char *id = NULL, name = NULL;
name = get_char_pointer();
这样连续定义指针,导致name并未定义成指针,⽽是定义成了⼀个int型。
要么定义成char* id = NULL, *name = NULL; 要么分开定义。
6. 警告: 传递‘pthread_create’的第 3 个参数时在不兼容的指针类型间转换 [-Wincompatible-pointer-types]
pthread_create原型:int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,void *(*start_rtn)(void*),void *arg);
可见第三个参数返回值是void*类型,参数是void*类型,这种错误⼀般要么是第三个参数返回值写成了void,要么是参数不是void*。
出现参数不兼容转换的警告,基本都是这个原因。
调⽤者:static void thread_func(void arg),
pthread_create(&pid, NULL, thread_func, NULL);
编译便会警告。
7. 警告: ‘av_free_packet’ is deprecated [-Wdeprecated-declarations]
表明av_free_packet函数已经过时,不建议使⽤,由于库在更新迭代过程中产⽣新的函数,旧的函数不再建议使⽤,所以调⽤旧函数时编译会产⽣警告。
8. 警告: 函数返回局部变量的地址 [-Wreturn-local-addr]
在⼀个函数⾥定义了⼀个局部变量,结束时返回这个局部变量的地址,就会出现该警告。因为局部变量是在栈中申请的空间,函数执⾏完后该空间会⾃动被释放回收,所以可能你调⽤这个函数,获取到的返回值并不是你想要的,可能是随机值。也可以说是返回的这个局部变量指针是⼀个野指针,虽然返回给你了想要的数据,但是这块内存会被别的地⽅malloc使⽤,所以最好不要返回局部变量地址,否则后果可能很严重。
9. 警告: 数组下标类型为‘char’ [-Wchar-subscripts]
调⽤者:char index = 0; char ip[16] = {0}; for(…){ip[index++] = “192.168.1.1”;}。因为char类型的变量值可能是负数,所以可能出现ip[index]取到负数索引的数组元素,⽐如ip[-1],因此编译会有警告。可以把char index 换成 unsigned char index或者int index,但是⾄于int index为什么不报错,这个不太清
楚了,可能int表⽰范围很⼤,⼀般不会越界变成负数吧。
10. 警告: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
原因是const修饰的指针变量赋值给了普通指针变量。那么const修饰的指针变量就有可能被修改,这是不允许的。
调⽤者:const char* p1; char* p2 = p1;
11. 警告:"xxxxx"重定义
11. 警告:"xxxxx"重定义
代码中某些宏定义在不同的⽂件中被多次定义,⽐如多个头⽂件都有如下定义:#define MAX(a,b) a>b?a:b,在编译过程中就会出现MAX重定义的问题,可将定义改为如下形式,消除警告:
#ifndef MAX
#define MAX(a,b) a>b?a:b
#endif
12. 警告: 反斜杠和换⾏为空格所分隔
调⽤者:#define HTTP_POST “POST %s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: /\r\n”\
其原因是最后⼀个反斜杠后⾯加了空格,反斜杠换⾏不能加空格,否则会出现这个警告
13. 错误:while running ’ aclocal ’ ,autogen.sh :1:eval:aclocal :not found
此错误发⽣在编译valgrind的时候执⾏./autogen.sh,先执⾏sudo apt-get install automake,安装必要的依赖和库,再执
⾏./autogen.sh即可解决。
14. 警告: assignment from incompatible pointer type
翻译:不兼容的指针类型转换,常见的使⽤情形如下:
char array[20] = {0}; poiner_func(&array);
编译警告:int poiner_func(char* p)需要⼀个char*类型的指针,⽽传⼊的是cha(*)[20]类型的指针。
15. 错误: 对未指定边界的数组的使⽤⽆效
调⽤者:
int array_pointer_func(char(*p)[],int col_size)
{
....
p =(char(*)[col_size])malloc(sizeof(char)*10);//注意数组指针分配内存的写法
strlcpy(p([idx], data,sizeof(p[idx]));//这⼀⾏报错
}
//函数修改为:
int array_pointer_func(char(*p)[64])
{
....
p =(char(*)[64])malloc(sizeof(char)*10);
strlcpy(p([idx], data,sizeof(p[idx]));//编译通过
}
具体原因:由于第⼀个函数的第⼀个参数没有指明第⼆维度,虽然第⼆个参数传⼊的是第⼆维度的⼤⼩,但是编译器并不知道,除⾮在函数⾥给第⼆维度也分配空间。这⾥注意给数组指针分配内存的写法。
16. 错误:expected declaration or statement at end of input
1、某⼀个函数或者变量没有在使⽤之前声明。
2、某个地⽅少了个括号。(并不⼀定是编译器指出错误的地⽅,这种情况,编译器⼀般会在最后⼀⾏代码报错,但错误很可能不在最
后⼀⾏,要靠⾃⼰去出来)
17. 警告:"usleep"和"popen"等函数隐式声明
虽然包含了头⽂件<unistd.h>,但是编译时仍提⽰隐式声明,原因是编译时加了-std=c99参数,改成-std=gnu99或者去掉即可18. error: variable ‘xxx’ has initializer but incomplete type
包含相应的头⽂件即可
No pains,no gains.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论