web-dev-qa-db-ja.com

Cの関数のサイズが常に1バイトなのはなぜですか?

sizeof()を使用して関数のサイズを確認すると、常に1バイトが得られます。この1バイトは何を意味していますか?

87
user1645461

これは制約違反であり、コンパイラが診断する必要があります。それにもかかわらずそれをコンパイルする場合、プログラムは未定義の動作をします[障害モードの説明について@Steve Jessopに感謝し、一部のコンパイラがこれを許可する理由について @ Michael Burrの回答 を参照してください]:からC11、6.5.3.4。/ 1:

sizeof演算子は、関数型の式には適用されません

80
Kerrek SB

これは未定義の動作ではありません。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でエラーにします。

56
Michael Burr

これは、コンパイラの作成者が悪魔を鼻から飛ばすのではなく、値1を決定したことを意味します(実際、sizeofの未定義の別の使用が原因で、「Cコンパイラ自体が診断を発行する必要がありますこれがプログラムからの最初の必要な診断であり、その後、それ自体が悪魔を鼻から飛ばす場合があります(ちなみに、文書化された診断メッセージである可能性があります)。ルールまたは制約(または、その点については、それが選択する理由)。」 https://groups.google.com/forum/?fromgroups=#!msg/comp.std。 c/ycpVKxTZkgw/S2hHdTbv4d8J

これから、コンパイラが未定義の構造に応じて行うことを決定するあらゆるものを表す「鼻の悪魔」という俗語があります。 1は、この場合のこのコンパイラの鼻の悪魔です。

13
Jon Hanna

他の人が指摘したように、sizeof()は任意の有効な識別子をとることができますが、関数名に対して有効な(正直真実かつ有効な)結果を返しません。さらに、「鼻の外の悪魔」症候群を引き起こす可能性があります。

プログラム関数サイズのプロファイルを作成する場合は、中間結果ディレクトリ(物が.obj/.oにコンパイルされる場所、または結果の画像/実行可能ファイルが配置される場所)にあるリンカーマップを確認してください。時々、このマップファイルを生成するかしないかのオプションがあります...それはコンパイラ/リンカーに依存します。

関数へのポインタのサイズが必要な場合、それらはすべて同じサイズ、つまりCPU上のアドレッシングWordのサイズです。

7
jpinto3912