sizeof()
を使用して関数のサイズを確認すると、常に1バイトが得られます。この1バイトは何を意味していますか?
これは制約違反であり、コンパイラが診断する必要があります。それにもかかわらずそれをコンパイルする場合、プログラムは未定義の動作をします[障害モードの説明について@Steve Jessopに感謝し、一部のコンパイラがこれを許可する理由について @ Michael Burrの回答 を参照してください]:からC11、6.5.3.4。/ 1:
sizeof
演算子は、関数型の式には適用されません
これは未定義の動作ではありません。C言語標準では、sizeof
演算子の制約違反であるため、関数指定子(関数名)でsizeof
演算子を使用するときに診断が必要です。
ただし、C言語の拡張機能として、GCCはvoid
ポインターおよび関数ポインターの演算を許可します。これは、void
または関数のサイズを1
として扱うことによって行われます。結果として、sizeof
演算子はvoid
またはGCCの関数に対して1
に評価されます。 http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith を参照してください
GCCに-pedantic
または-Wpointer-arith
オプションを使用することにより、これらのオペランドでsizeof
を使用するときにGCCに警告を発行させることができます。または、-Werror=pointer-arith
でエラーにします。
これは、コンパイラの作成者が悪魔を鼻から飛ばすのではなく、値1を決定したことを意味します(実際、sizeof
の未定義の別の使用が原因で、「Cコンパイラ自体が診断を発行する必要がありますこれがプログラムからの最初の必要な診断であり、その後、それ自体が悪魔を鼻から飛ばす場合があります(ちなみに、文書化された診断メッセージである可能性があります)。ルールまたは制約(または、その点については、それが選択する理由)。」 https://groups.google.com/forum/?fromgroups=#!msg/comp.std。 c/ycpVKxTZkgw/S2hHdTbv4d8J
これから、コンパイラが未定義の構造に応じて行うことを決定するあらゆるものを表す「鼻の悪魔」という俗語があります。 1
は、この場合のこのコンパイラの鼻の悪魔です。
他の人が指摘したように、sizeof()は任意の有効な識別子をとることができますが、関数名に対して有効な(正直真実かつ有効な)結果を返しません。さらに、「鼻の外の悪魔」症候群を引き起こす可能性があります。
プログラム関数サイズのプロファイルを作成する場合は、中間結果ディレクトリ(物が.obj/.oにコンパイルされる場所、または結果の画像/実行可能ファイルが配置される場所)にあるリンカーマップを確認してください。時々、このマップファイルを生成するかしないかのオプションがあります...それはコンパイラ/リンカーに依存します。
関数へのポインタのサイズが必要な場合、それらはすべて同じサイズ、つまりCPU上のアドレッシングWordのサイズです。