9

Linuxカーネルは初めてです。私はファイルを読んでいます、そこで私はこのように見えるioctl.hマクロに遭遇しました :_IOC_TYPECHECK(t)

#define _IOC_TYPECHECK(t) \
        ((sizeof(t) == sizeof(t[1]) && \
          sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
          sizeof(t) : __invalid_size_argument_for_IOC)

このコードを説明してもらえますか?このコードでは、どういうsizeof(t[1])意味ですか?

4

2 に答える 2

8

_IOR//これは_IOW_IOWR型であるはずのマクロに対する 3 番目のパラメータの有効性をチェックするために使用されます。パラメーターが実際に型 (変数や数値ではない) であることを確認し、それ以外の場合はコンパイラ エラーまたはリンカー エラーを引き起こします。

  • tが型の場合、型t[1]は「1 の配列t」です。この型は と同じサイズなtのでsizeof(t) == sizeof(t[1])真です。

  • tが数値の場合sizeof(t)、コンパイルに失敗します。

  • tが単純な (配列ではない) 変数の場合、t[1]コンパイラ エラーが発生します。

  • tが配列変数の場合はsizeof(t) == sizeof(t[1])false となり、リンカエラーとなります(__invalid_size_argument_for_IOCが定義されていないため)。

この式sizeof(t) < (1 << _IOC_SIZEBITS)は、型のサイズが にt許可されている最大値を超えていないことを確認し、ioctlそれ以外の場合は同じリンカ エラーを引き起こします。

このマクロではキャッチされない無効なケースがまだいくつかあります。たとえば、tがポインターへのポインターである場合などです。

于 2013-02-18T10:51:26.480 に答える
3

の他のすべての用法と同じ意味ですsizeof。式のサイズを計算します。

tこの特定のケースでは、チェックは、コンテキストからはわからない (変数ではなく型名である必要がある) のプロパティを確認することを目的としていると思われます...おそらく、それを一部の型を除外するポインター (配列のインデックス付けに必要)。マクロの横のコメントは、/* provoke compile error for invalid uses of size argument */この理論をサポートしているように見えるものを示しています。

sizeofは関数ではなく演算子であることに注意してください。型のサイズを直接計算する場合を除き、かっこは必要ありません。これらは式の一部です (キャスト式です)。sizeof t == sizeof t[1] && ...したがって、これは、または(sizeof t == sizeof t[1])わかりやすくするために書くことができます。

の型を繰り返す代わりに、計算されるサイズを適切な配列に「ロック」するため、これは使用するのに非常に適したスタイルですt。したがって、型が変更された場合、式は自動的に適応し、正しいものを計算します。

sizeof多くの C プログラマーは、何らかの理由で、すべての場合に引数を括弧で囲むことを好むようです。

于 2013-02-18T10:38:58.630 に答える