GCC警告选项例解_第1页
GCC警告选项例解_第2页
GCC警告选项例解_第3页
GCC警告选项例解_第4页
GCC警告选项例解_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

GCC 警告选项例解 程序员是追求完美的一族 即使是一般的程序员大多也都不想看到自己的程序中有甚至那么一点点的瑕疵 遇到任意 一条编译器警告都坚决不放过 有人会说 我们可以使用比编译器更加严格的静态代码检查工具 如 splint 这个建 议也很不错 不过 lint 工具使用起来较繁琐 有时候还需要记住一些特定符号并插入到你自己的代码中才行 门槛较 高 这也让很多人止步于此 那么我 们就从此放弃么 不 如今的编译器做得都很好 它可以帮助我们的找到绝大多 数可能出现问题的代码 前提是你要学会控制编译器去找到这些问题代码 而熟悉编译器的警告选项恰恰是体现控制 力的好方法 当你可以自如控制编译器警告输出的时候 你就算是 入道 了 同时你对语言的理解也更进一步了 有人说 我就是用一个 Wall 选项就可以了 一般选手可以这么做 而且他可以不知道 Wall 会跟踪哪些类型的问题 但是高级选手是不会只使用 Wall 的 他会把每条警告都研究的很透彻 会在 Makefile 中列出他想让编译器输出哪些 类型的警告以替代 Wall 他会屏蔽掉那些对他的代码 毫无用处 的警告 很可能他使用了编译器对语言的扩展功能 他 会有个和编译器交流的过程 俗话说 工欲善其事 必先利其器 一直在工作中使用 GNU C 编译器 以下简称 GCC 这里对 GCC 的一些警告选项 细致的分析 并列举几个简单的例子 注 1 供分析参考 1 Wall 集合警告选项 我们平时可能大多数情况只使用 Wall 编译警告选项 实际上 Wall 选项是一系列警告编译选项的集合 下面逐一分析 这一集合中的各个选项 Wchar subscripts 如果数组使用 char 类型变量做为下标值的话 则发出警告 因为在某些平台上 char 可能默认为 signed char 一旦溢 出 就可能导致某些意外的结果 e g test signed char c include int main char c 255 我们以为 char 是无符号的 其范围应该是 0 255 int i 0 int a 256 for i 0 i 256 i a i 1 printf d n c 我们期待输出 255 printf d n a c 我们期待输出 1 printf d n a 255 return 0 gcc Wchar subscripts test signed char c test signed char c In function main test signed char c 13 warning array subscript has type char 其输出结果 1 4197476 1 从输出结果来看 Solaris 9 gcc 3 2 上 char 默认实现类型为 signed char 在 Windows XP gcc 3 4 2 上也是一样 Windows 上的输出结果 1 16 随机值 1 Wcomment 当 出现在 注释中 或者 出现在 注释结尾处时 使用 Wcomment 会给出警告 不要小觑这些马虎 代码 它很可能会影响程序的运行结果 如下面的例子 e g test comment c gcc Wcomment test comment c include int main int a 1 int b 2 int c 0 ok just test c a b 这里我们期待 c 3 但实际上输出 c 0 printf the c is d n c return 0 gcc Wcomment test comment c test comment c 10 30 warning multi line comment test comment c 15 12 warning within comment 输出 the c is 0 Wformat 检查 printf 和 scanf 等格式化输入输出函数的格式字符串与参数类型的匹配情况 如果发现不匹配则发出警告 某些 时候格式字符串与参数类型的不匹配会导致程序运行错误 所以这是个很有用的警告选项 e g test format c include int main long l 1 double d 55 67 printf d n l printf d n d return 0 gcc Wformat test format c test format c In function main test format c 10 warning int format long int arg arg 2 test format c 11 warning int format double arg arg 2 输出 1 1078711746 Wimplicit 该警告选项实际上是 Wimplicit int 和 Wimplicit function declaration 两个警告选项的集合 前者在声明函数却 未指明函数返回类型时给出警告 后者则是在函数声明前调用该函数时给出警告 e g test implicit c include add int a int b 函数没有声明返回类型 return a b int test int a 0 int b 0 int c 0 int d 0 c add a b d sub a b 未声明 sub 的函数原型 return 0 gcc Wimplicit c test implicit c test implicit c 7 warning return type defaults to int test implicit c In function test test implicit c 18 warning implicit declaration of function sub Wmissing braces 当聚合类型或者数组变量的初始化表达式没有 充分 用括号 括起时 给出警告 文字表述很难理解 举例说明则清晰 些 看下面的例子 e g test missing braces c struct point int x int y struct line struct point start struct point end typedef struct line line int main int array1 2 2 11 12 13 14 int array2 2 2 11 12 13 14 ok line l1 1 1 2 2 line l2 2 2 3 3 ok return 0 gcc Wmissing braces test missing braces c test missing braces c In function main test missing braces c 19 warning missing braces around initializer test missing braces c 19 warning near initialization for array1 0 test missing braces c 21 warning missing braces around initializer test missing braces c 21 warning near initialization for l1 start Wparentheses 这是一个很有用的警告选项 它能帮助你从那些看起来语法正确但却由于操作符优先级或者代码结构 障眼 而导致错误 运行的代码中解脱出来 好长的一个长句 还是看例子理解吧 e g test parentheses c gcc Wparentheses test parentheses c include int main int a 1 int b 1 int c 1 int d 1 if a if a 12 if b d 9 else d 10 从代码的缩进上来看 这句仿佛是 if a 12 的 else 分支 printf the d is d n d 期待 d 10 而结果却是 1 return 0 gcc Wparentheses test parentheses c test parentheses c In function main test parentheses c 13 warning suggest parentheses around i i printf the i is d n i return 0 gcc Wsequence point test sequence point c test sequence point c In function main test sequence point c 10 warning operation on i may be undefined 在两个平台上给出的编译警告都是一致的 但是输出结果却大相径庭 Solaris 输出 the i is 11 Windows 输出 the i is 12 类似的像这种与顺序点相关的代码例子有 i i a i b i a i i 等等 Wswitch 这个选项的功能浅显易懂 通过文字描述也可以清晰的说明 当以一个枚举类型 enum 作为 switch 语句的索引时但 却没有处理 default 情况 或者没有处理所有枚举类型定义范围内的情况时 该选项会给处警告 e g test switch1 c enum week SUNDAY MONDAY TUESDAY only an example we omitted the others int test1 enum week w SUNDAY switch w case SUNDAY break without default or the other case handlings return 0 int test2 Ok won t invoke even a warning enum week w SUNDAY switch w case SUNDAY break default break return 0 int test3 Ok won t invoke even a warning enum week w SUNDAY switch w case SUNDAY break case MONDAY break case TUESDAY break return 0 gcc Wswitch c test switch c test switch c In function test1 test switch c 16 warning enumeration value MONDAY not handled in switch test switch c 16 warning enumeration value TUESDAY not handled in switch Wunused Wunused 是 Wunused function Wunused label Wunused variable Wunused value 选项的集合 Wunused parameter 需单独使用 1 Wunused function 用来警告存在一个未使用的 static 函数的定义或者存在一个只声明却未定义的 static 函数 参见下面例子中的 func1 和 func2 2 Wunused label 用来警告存在一个使用了却未定义或者存在一个定义了却未使用的 label 参加下面例子中的 func3 和 func7 3 Wunused variable 用来警告存在一个定义了却未使用的局部变量或者非常量 static 变量 参见下面例子中 func5 和 var1 4 Wunused value 用来警告一个显式计算表达式的结果未被使用 参见下面例子中 func6 5 Wunused parameter 用来警告一个函数的参数在函数的实现中并未被用到 参见下面例子中 func4 下面是一个综合的例子 e g test unused c static void func1 to prove function used but never defined static void func2 to prove function defined but not used static void func3 to prove label used but never defined static void func7 to prove label defined but never used static void func4 int a to prove parameter declared but not used static void func5 to prove local variable defined but not used static void func6 to prove value evaluated but not used static int var1 void test func1 func3 func4 4 func5 func6 static void func2 do nothing static void func3 goto over static void func4 int a do nothing static void func5 int a 0 static void func6 int a 0 int b 6 a b gcc Wunused parameter c test unused c 如果不是用 Wunused parameter 则 func4 函数将不被警告 test unused c In function func3 test unused c 30 label over used but not defined test unused c In function func7 test unused c 35 warning deprecated use of label at end of compound statement test unused c 34 warning label over defined but not used test unused c In function func4 test unused c 37 warning unused parameter a test unused c In function func5 test unused c 42 warning unused variable a test unused c In function func6 test unused c 48 warning statement with no effect test unused c At top level test unused c 6 warning func1 used but never defined test unused c 25 warning func2 defined but not used test unused c 14 warning var1 defined but not used Wuninitialized 该警告选项用于检查一个局部自动变量在使用之前是否已经初始化了或者在一个 longjmp 调用可能修改一个 non volatile automatic variable 时给出警告 目前编译器还不是那么 smart 所以对有些可以正确按照程序员的意思运行 的代码还是给出警告 而且该警告选项需要和 O 选项一起使用 否则你得不到任何 uinitialized 的警告 e g test uninitialized c int test int y int x switch y case 1 x 11 break case 2 x 22 break case 3 x 33 break return x gcc Wuninitialized O c test uninitialized c test uninitialized c In function test test uninitialized c 6 warning x might be used uninitialized in this function 2 非 Wall 集合警告选项 以下讨论的这些警告选项并不包含在 Wall 中 需要程序员显式添加 Wfloat equal 该项用来检查浮点值是否出现在相等比较的表达式中 e g test float equal c void test int i double d 1 5 if d i gcc Wfloat equal c test float equal c test float equal c In function test test float equal c 8 warning comparing floating point with or is unsafe Wshadow 当局部变量遮蔽 shadow 了参数 全局变量或者是其他局部变量时 该警告选项会给我们以警告信息 e g test shadow c int g void test int i short i double g gcc Wshadow c test shadow c test shadow c In function test test shadow c 9 warning declaration of i shadows a parameter test shadow c 10 warning declaration of g shadows a global declaration test shadow c 6 warning shadowed declaration is here Wbad function cast 当函数 准确地说应该是函数返回类型 被转换为非匹配类型时 均产生警告 e g test bad func case c int add int a int b return a b void test char p char add 1 13 gcc Wbad function cast c test bad func case c test bad func case c In function test test bad func case c 11 warning cast does not match function type Wcast qual 当去掉修饰源 Target 的限定词 如 const 时 给出警告 e g test cast qual c void test char c 0 const char p char q q char p gcc Wcast qual c test cast qual c test cast qual c In function test test cast qual c 10 warning cast discards qualifiers from pointer target type Wcast align 这是个非常有用的选项 特别是对于在 Solaris 这样的对内存对齐校验的平台尤其重要 它用于在从对齐系数小的地址 如 char 转换为对齐系数大的地址 如 int 转换时给出警告 e g test cast align c include int main char c 1 char p ok int q int p bad align cast printf the q is d n q return 0 gcc Wcast align test cast align c test cast align c In function main test cast align c 9 warning cast increases required alignment of target type 输出 总线错误 主存储器 信息转储 on Solaris 9 Wsign compare 在有符号数和无符号数进行值比较时 有符号数可能在比较之前被转换为无符号数而导致结果错误 使用该选项会对 这样的情况给出警告 e g test sign compare c include int main unsigned int i 128 signed int j 1 if i j printf i j n return 0 gcc Wsign compare test sign compare c test sign compare c In function main test sign compare c 10 warning comparison between signed and unsigned 输出 i j Waggregate return 如果一个函数返回一个聚合类型 如结构体 联合或者数组 该选项就会给出警告信息 较简单不举例了 Wmultichar 当我们写下如此代码时 char c peter 使用该选项会给出警告 这个选项是默认选项 你无需单独使用该选项 不 过你可以使用 Wno multichar 来关闭这些警告信息 但是这可是不建议你去做的 对于 char c peter 这样的代码 的处理是与平台相关 不可移植的 e g test multichar c int main char c peter printf c is c n c return 0 但这里在 Windows 和 Solaris 平台输出的结果却一致 c is r Wu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论