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