一部の移植不可能なコードは、lint のデフォルトの動作によってフラグを付けられます。また、ほかにも少数の状況で、 -p または -Xc を指定して lint を起動すると、診断されることがあります。lint は ISO C 規格に一致しない言語構造を検査します。-p および -Xc のもとで発行されるメッセージに関しては、「4.6.2 lint ライブラリ」を参照してください。
次に例を示します。
一部の C 言語の実装では、signed または unsigned のどちらも明示的に宣言されていない文字変数は、符号付き (signed) の量として扱われ、通常は -128 ~ 127 の範囲になります。ほかの実装では、これらは負にならない量として扱われ、通常は 0 ~ 255 の範囲になります。そのため次のテストは
char c; c = getchar(); if (c == EOF) ... |
そこで EOF が値 -1 を持つテストは、文字変数が負でない値を取るマシンでは常に失敗します。-p オプションで呼び出した lint は、普通の char が負の値を取る可能性があるような比較をすべて検査します。しかし前述の例では、c を signed char で宣言しても、問題が除去されるのではなく診断が除去されるだけです。これは、getchar() が入力可能な文字と明確な EOF 値を返さなければならず、char がその値を格納することができないためです。これは、処理系ごとに定義される符号拡張から生ずるもっとも一般的な例です。これにより、lint の移植性オプションを注意深く使用すると移植性に関係しないバグを発見するのに役立つということがわかります。ここでは c を int で宣言します。
同様の問題がビットフィールドにもあります。定数値がビットフィールドに代入される場合、その値を保持するにはフィールドが小さすぎる場合があります。int 型のビットフィールドを符号なし (unsigned) の量として取り扱うマシンでは、int x:3 の範囲で許可される値が 0 ~ 7 であるのに対し、符号付き (signed) の量として取り扱うマシンでは -4 ~ 3 になります。ただし、int 型として宣言された 3 ビットのフィールドは、後者のマシンでは値 4 を保持できません。-p を指定して呼び出された lint は、unsigned int または signed int を除き、すべてのビットフィールドの型にフラグを付けます。これらのみが、移植可能なビットフィールド型です。コンパイラは、ビットフィールドの型 int、char、short、および long をサポートしますが、これらは unsigned、signed またはそのどちらでもない場合があります。さらにコンパイラは enum のビットフィールドの型もサポートします。
大きなサイズの型が小さなサイズの型に代入されると、バグが発生することがあります。有効なビットが切り捨てられると正確な値を保持できなくなります。
short s; long l; s = l; |
lint は、デフォルトでこのような代入すべてを知らせます。診断は、-a オプションを指定して呼び出すことにより抑制することができます。どのオプションを指定して lint を呼び出しても、ほかの診断をも抑制する可能性があることに注意してください。2 つ以上の診断を抑制するオプションについては、「4.6.2 lint ライブラリ」にあるリストを参照してください。
あるオブジェクト型へのポインタをより厳密な境界整列要求を持つオブジェクト型のポインタにキャストすると、移植性がなくなることがあります。lint のフラグは次のようになります。
int *fun(y) char *y; { return(int *)y; } |
大部分のマシンでは、int は char とは異なり任意のバイト境界から開始することができないため、lint はフラグを立てます。-h を指定して lint を実行することによってこの診断を抑制することができます。この場合もまた、ほかのメッセージを抑制する可能性があります。汎用ポインタ void * を使用すればほかの影響を回避することができます。
ISO C は、複雑な式の評価順序を定義していません。この意味は、関数呼び出し、入れ子になった代入文、またはインクリメントとデクリメント演算子から副作用が生じる場合 (すなわち、式評価の副作用として変数が変更される時)、副作用の生じる順序はマシンへの依存度が高いということです。デフォルトでは、lint は副作用で変更されたり同一式内でほかの場所に使用される変数を知らせます。
int a[10]; main() { int i = 1; a[i++] = i; } |
この例での a[1] の値は、あるコンパイラでは 1、別のコンパイラでは 2 という可能性もあります。ビット単位の論理演算子 & がこのような診断をもたらすことがあるのは、誤って 論理演算子 && の代わりに使用される場合です。
if ((c = getchar()) != EOF & c != ’0’) |