继续收集gcc一些编译警告

588 阅读3分钟

这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战

本文继续收到关于gcc编译警告。文中提到的警告,都是在日常工作或项目中遇到的。解决警告是件麻烦磨人的事,但历练之后,就能积累一定的编码素养,当提高一个层次后,代码质量也能得到保证,至少能避免一些低级的错误,无论对公司项目或个人成长,都是有好处的。

1、调试语句的警告

警告:

warning: value computed is not used

出错示例代码:

#define LL_DEBUG printf("[%s-%s:%d]", __FILE__,__FUNCTION__, __LINE__) && printf//LEVEL_PRINT("[%s:%d]", __FILE__, __LINE__) && LEVEL_PRINT

问题出现在&&上。其实代码意图很简单,就是打印信息同时把行号、函数打印出来。可能因为行码太过匆忙,就出现上述这样的代码了。修改很简单,如下:

#define LL_DEBUG(fmt, ...) printf("[%s-%s:%d]" fmt, __FILE__,__FUNCTION__, __LINE__, ##__VA_ARGS__)

瞬间人感觉正常了。
同样是调试语句,警告如下:

warning: statement has no effect [-Wunused-value]

出错示例代码:

#if 0
#define LL_DEBUG printf
#else
#define LL_DEBUG
#endif

这样的语句肯定不行的。修正:

#if 0
#define LL_DEBUG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define LL_DEBUG(fmt, ...)
#endif

2、类型匹配

警告:

warning: format '%d' expects type 'int*', but argument 6 has type 'unsigned short*'

unsigned short和%d不匹配。用%hu来修正,示例: sscanf("test: 250", "test: %hu", &uWord);。下面从一些参考资料上获取并验证的:

short: %hd
unsigned short: %hu
unsigned int: %u
unsigned long long: %llu

3、变量未初始化

警告:

warning: 'mode' may be used uninitialized in this function

原因是mode在声明时没有初始化,但后面有条件地被赋值,不满足所有情况,编译器报警告。 比如:

int mode;
if (idx > 1)
{
    mode = 1;
}
int set = mode;

假如idx小于1,mode就不会被赋值,set的值就是未知的了(看编译器)。

4、其它

警告:

warning: backslash and newline separated by space

宏后面使用“\”来连接多行,但“\”后面多了空格,删除空格即可。
警告:

warning: "/*" within comment [-Wcomment]

/***/中还有/*,有这个警告,我会认为写代码的人细心度不够,写代码如行云流水。呵呵。

5、新版本带来的警告

警告:

error: macro "__DATE__" might prevent reproducible builds [-Werror=date-time]
error: macro "__TIME__" might prevent reproducible builds [-Werror=date-time]

gcc4.9及新版本,添加了-Werror=date-time,不能在代码中使用__DATE____TIME__,否则会出现错误(gcc说法是会导致编译的不确定性),如果一定要用,则在编译时添加-Wno-error=date-time,但依然会有警告打印。

6、动态库版本问题

错误:

/bin/ld: CThread.o: relocation R_X86_64_32 against `.bss' can not be used when making a shared object; recompile with -fPIC
/bin/ld: common.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/bin/ld: utils.o: relocation R_X86_64_32S against symbol `_ZTVN3hwx13CPathCreateE' can not be used when making a shared object; recompile with -fPIC
/bin/ld: CBmp.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC

解决:所有的.o使用-fPIC编译,在链接即生成.so阶段用-shared选项。