Oracle® Developer Studio 12.5:C 用户指南

退出打印视图

更新时间: 2016 年 7 月
 
 

5.4 lint 消息

lint 的大多数消息都很简单,对于它们诊断的每个问题都打印一行语句。对于包含的文件中检测到的错误,编译器会报告多次,而 lint 仅报告一次(无论其他源文件中包含该文件多少次)。文件之间存在不一致时会发出复合消息,并且在少数情况下,文件内部存在问题时也会发出复合消息。单个消息描述所检查的文件中的各个问题。如果使用 lint 过滤器要求对出现的每个问题都输出一条消息,可通过调用带有 -s 选项的 lint 将复合诊断转换为简单类型。有关更多信息,请参见lint 库

lint 的消息会写入 stderr

5.4.1 用于禁止消息的选项

可以使用多个 lint 选项来禁止 lint 诊断消息。可以使用后跟一个或多个 tags-erroff 选项来禁止消息。 可以使用 -errtags=yes 选项显示这些助记符标记。

下表列出了用于禁止 lint 消息的选项。

表 15  用于禁止消息的 lint 选项
选项
禁止的消息
-a
assignment causes implicit narrowing conversion
conversion to larger integral type may sign-extend incorrectly
-b
statement not reached (unreachable break and empty statements)
-h
assignment operator "=" found where equality operator "==" was expected
constant operand to op: "!"
fallthrough on case statements
pointer cast may result in improper alignment
precedence confusion possible; parenthesize
statement has no consequent: if
statement has no consequent: else
-m
declared global, could be static
-erroff=tag
tag 指定的一条或多条 lint 消息
-u
name defined but never used
name used but not defined
-v
arguments unused in function
-x
name declared but never used or defined

5.4.2 lint 消息格式

lint 程序可以使用某些选项显示精确的源文件行,并将指针指向发生错误的行位置。 启用此功能的选项为 -errfmt=f,将使 lint 提供以下信息:

  • 源代码行和位置

  • 宏展开

  • 有错误倾向的堆栈

例如,以下程序 Test1.c 包含一个错误。

1 #include <string.h>
2 static void cpv(char *s, char* v, unsigned n)
3 { int i;
4   for (i=0; i<=n; i++){
5        *v++ = *s++;}
6 }
7 void main(int argc, char* argv[])
8 {
9     if (argc != 0){
10        cpv(argv[0], argc, strlen(argv[0]));}
11}

Test1.c 中使用带 —errfmt=src 选项的 lint 将生成以下输出:

% lint -errfmt=src-Nlevel=2 Test1.c
      |static void cpv(char *s, char* v, unsigned n)
      |            ^  line 2, Test1.c
      |
      |         cpv(argv[0], argc, strlen(argv[0]));
      |                      ^  line 10, Test1.c
warning: improper pointer/integer combination: arg #2
      |
      |static void cpv(char *s, char* v, unsigned n)
      |                               ^  line 2, Test1.c
      |
      |cpv(argv[0], argc, strlen(argv[0]));
      |                       ^ line 10, Test1.c
      |
      |        *v++ = *s++;
      |         ^  line 5, Test1.c
warning: use of a pointer produced in a questionable way
    v defined at Test1.c(2)    ::Test1.c(5)
      call stack:
          main()                ,    Test1.c(10)
          cpv()                 ,    Test1.c(5)

第一个警告指示互相矛盾的两个源代码行。第二个警告显示调用堆栈以及导致错误的控制流。

另一个程序 Test2.c 包含一个不同的错误:

1 #define AA(b) AR[b+l]
2 #define B(c,d) c+AA(d)
3
4 int x=0;
5
6 int AR[10]={1,2,3,4,5,6,77,88,99,0};
7
8 main()
9  {
10  int y=-5, z=5;
11  return B(y,z);
12 }

Test2.c 中使用带 —errfmt=macro 选项的 lint 将生成以下输出,并显示宏替换步骤:

% lint -errfmt=macro Test2.c
      | return B(y,z);
      |        ^  line 11, Test2.c
      |
      |#define B(c,d) c+AA(d)
      |                 ^  line 2, Test2.c
      |
      |#define AA(b) AR[b+l]
      |                   ^  line 1, Test2.c
error: undefined symbol: l
|
      |    return B(y,z);
      |           ^  line 11, Test2.c
      |
      |#define B(c,d) c+AA(d)
      |                 ^  line 2, Test2.c
      |
      |#define AA(b) AR[b+l]
      |                   ^  line 1, Test2.c
variable may be used before set: l
lint: errors in Test2.c; no output created
lint: pass2 not run - errors in Test2.c