Sun Studio 12:C 用户指南

4.6.1 由 lint 执行的诊断

对以下三种主要条件执行特定于 lint 的诊断:不一致的使用、不可移植的代码以及可疑的构造。在本节中,我们将研究在每种条件下 lint 的行为示例,并针对它们引起的问题提供可能的解决方法建议。

4.6.1.1 一致性检查

在文件内部以及各文件之间检查使用变量、参数和函数的不一致性。一般说来,对原型的使用、声明和参数执行的检查lint 对旧样式函数执行的检查相同。如果程序未使用函数原型,lint 将比编译器更严格地检查每个函数调用中参数的数量和类型。lint 还标识 [fs]printf()[fs]scanf() 控制字符串中转换定义和参数之间的不匹配。

示例:

4.6.1.2 可移植性检查

lint 的缺省行为会标记某些不可移植的代码,如果使用 -p-Xc 调用 lint 还会诊断其他一些情况。后者导致 lint 检查不符合 ISO C 标准的构造。有关使用 -p-Xc 时发出的消息,请参见4.6.2 lint

示例:


char c;
c = getchar();
if (c == EOF) ...

其中 EOF 的值为 -1,在字符变量取非负值的计算机上总是失败。使用 -p 调用的 lint 会检查暗示无格式 char 可取负值的所有比较。然而,在以上示例中,将 c 声明为 signed char 可避免执行诊断,却无法避免出现该问题。这是因为 getchar() 必须返回所有可能的字符和一个不同的 EOF 值,因此 char 无法存储其值。此示例可能是出自于实现定义的符号扩展的最常见示例,我们之所以引用该示例,是为了说明如何通过巧妙地应用 lint 的可移植性选项来帮助您发现与可移植性无关的错误。在任何情况下,将 c 声明为 int


short s;
long l;
s = l;

lint 在缺省情况下会标记所有此类赋值;可通过调用 -a 选项来禁止该诊断。请记住,使用此选项或任何其他选项调用 lint 时,可能会禁止其他诊断。请查看4.6.2 lint中的列表,以了解禁止多项诊断的选项。


int *fun(y)
char *y;
{
    return(int *)y;
}

这是因为在大多数计算机上,int 不能在一个任意字节边界上开始,而 char 则可以。可通过使用 -h 调用 lint 来禁止诊断,尽管这可能会再次禁用其他消息。但是最好通过使用通用指针 void * 来消除该问题。


int a[10];
main()
{
    int i = 1;
    a[i++] = i;
}

在此示例中,a[1] 的值在使用一个编译器时可能为 1,在使用另一个编译器时可能为 2。如果在逻辑运算符 && 的位置错误地使用了按位逻辑运算符 &,则会引起该诊断:


if ((c = getchar()) != EOF & c != ’0’)

4.6.1.3 可疑的构造

lint 会标记那些不能表达编程人员意图的各种合法构造。示例:


unsigned x;
if (x < 0) ...

总是失败。测试:


unsigned x;
if (x > 0) ...

等效于:


if (x != 0) ...

这可能不是预期的操作。lint 会标记 unsigned 变量与负常量或 0 的可疑比较。要将 unsigned 变量与负数的位模式进行比较,请将该变量的类型强制转换为 unsigned


if (u == (unsigned) -1) ...

或者使用 U 后缀:


if (u == -1U) ...

int fun()
{
    int a, b, x, y;
    (a = x) && (b == y);
}

if (x & a == 0) ...

求值如下:


if (x & (a == 0)) ...

这很有可能不是您的意图。如果使用 -h 调用 lint,则会禁用该诊断