を使用して関数のサイズを確認すると、sizeof()
常に1バイトが取得されます。この1バイトは何を意味していますか?
を使用して関数のサイズを確認すると、sizeof()
常に1バイトが取得されます。この1バイトは何を意味していますか?
回答:
これは制約違反であり、コンパイラが診断する必要があります。それにもかかわらずそれをコンパイルする場合、プログラムは未定義の動作をします[障害モードの説明について@Steve Jessopに感謝し、一部のコンパイラがこれを許可する理由について@Michael Burrの回答を参照してください]:C11から、6.5.3.4。/ 1:
sizeof
オペレータは、関数型を持つ式に適用してはなりません
-std=c11
ではなく でもあることに注意してくださいgnu11
。これは本当に奇妙なコンパイラ拡張です。
sizeof(void)
GNU Cの1である
-std=c11
:誰かが-std=c*
オプションを広告基準を参照する必要があります。それらは適合モードを有効にせず、整形式のプログラムがコンパイルするのを妨げる拡張機能(typeof
キーワードなど)を無効にするだけです。整形式のCプログラムはそれを変数名として使用できるためgcc
、デフォルトでは拒否されます。 )。不正な形式のプログラムが診断されずに通過することを許可する拡張機能をさらに無効にするには、-pedantic
またはが必要-pedantic-errors
です。
これは未定義の動作ではありません。C言語標準は、sizeof
演算子の制約違反であるため、sizeof
演算子を関数指定子(関数名)と一緒に使用するときに診断が必要です。
ただし、C言語の拡張機能として、GCCは、void
ポインターまたは関数ポインターの演算を許可します。これは、a void
または関数のサイズをとして扱うことによって行われ1
ます。結果として、sizeof
オペレーターは、GCC を使用1
するvoid
か、GCC を使用する機能を評価します。http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arithを参照してください
GCC sizeof
の-pedantic
or -Wpointer-arith
オプションを使用して、これらのオペランドを使用するときにGCCに警告を発行させることができます。または、でエラーにし-Werror=pointer-arith
ます。
sizeof
関数がUBでないことを除いて、私はUBについてほとんど何も述べていませんでした(他の回答がそれがUBであると述べたために、私はかなり言及しました)。しかし、おそらく私は文を構成した方法のためにそれを混乱させました。より明確にするために。sizeof
関数はUBではありません(いくつかの回答が主張しているように)。制約違反です。そのため、診断が必要です。GCCはそれを拡張として許可します。
それは、コンパイラの作成者が悪魔を鼻から飛ばすのではなく、値1を決定したことを意味します(実際、これは未定義の別の使用法でありsizeof
、式が与えられました。「これが最初に必要な場合、Cコンパイラ自体が診断を発行する必要があります。あなたのプログラムから生じた診断、そしてそれからそれ自体が悪魔をあなたの鼻から飛ばすかもしれません(ところで、それは構文規則または制約のさらなる違反のためにさらなる診断を発行するかもしれません)(または、文書化された診断メッセージであるかもしれません)その理由については、理由を問わず選択します)。」https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
これから、コンパイラが未定義の構造に応じて行うことを決定するあらゆるものを表す「鼻の悪魔」という俗語があります。1
この場合のこのコンパイラの鼻の悪魔です。
他の人が指摘したように、sizeof()は任意の有効な識別子をとることができますが、関数名に対して有効な(正直に言って真実で有効な)結果を返しません。さらに、「鼻の外の悪魔」症候群を引き起こす可能性があります。
プログラム関数のサイズをプロファイルする場合は、中間結果ディレクトリ(物が.obj / .oにコンパイルされる場所、または結果のイメージ/実行可能ファイルが配置される場所)にあるリンカーマップを確認してください。時々このマップファイルを生成するかしないかのオプションがあります...それはコンパイラ/リンカーに依存します。
関数へのポインタのサイズが必要な場合、それらはすべて同じサイズ、つまりCPUのアドレス指定ワードのサイズです。
int x = 1;
が、標準に準拠したコンパイラで許可されているのは1つだけです。sizeof()
機能に適用されて、それがまたは設定値を返す、またはコンパイルすることを拒否、または時間の特定のレジスタに何でもに基づいてランダムな値を返さない場合があります。文字通りの鼻の悪魔はほとんどありませんが、規格の書簡の範囲内です。
sizeof
へのポインターに適用します。
-pedantic
)、コンパイラーは非準拠であり、すべてのプログラムは未定義の動作をします。