パスワードを忘れた? アカウント作成
452240 journal

Endowsの日記: Endows の へっぽこプログラマ日誌 第6回リターンズ

日記 by Endows

sizeof の件について、我が友にしてプログラミングの師匠(大げさ?) Yoh2 さんよりメールをいただきました。転載許可も出てましたので、ここに転載。

---------- 以下、メール内容 ----------

Cの関数型を数学っぽく書くと

    f: (引数の型の対)→(戻り値)

てな感じになります。
例えば、
double power(double x, int n)
{
        double result = 1.;

        while(--n >= 0){
                result *= x;
        }
        return result;
}

の型は、(double × int)→doubleとなります。
さて、ここで注意しなければならないのは、これはあくまで「power」の型で
あるということ。

real(2., 10)のように、関数(real)に引数((2., 10))を喰わせたものの型は
すでに関数型ではなく、関数の戻り値の型となります。

同様に、main()の型は,関数mainに引数()(←空引数ね)を適用したものなので、
型はmainの戻り値であるintであるということになります。

最後に注意しなければならないのは、sizeof演算子は、引数の型のサイズを
返すだけで、その引数の値を評価するものではないということです。
もうちょっと言うと,sizeof(式)は、式の値を計算するのではなく、
式の型を計算するものだということです。

引数の値を評価しないのだから、引数を評価すると暴走するようなものでも、
そんなことは知ったことではないので、sizeofはそのまま戻り値のサイズを返します。

先程のpowerを例に取ると、
●sizeof(power(2., 10))の評価:
A powerの型: (double × int)→double
B 2.の型:double
C 10の型:int
D (2., 10)の型:B、Cよりdouble×int
E power(2., 10)の型:A、Dより、int
最後に、intの型のサイズは4
以上より、sizeof(power(2., 10))=4。

という、型の計算(型推論)をします。(本当はたぶんもっと複雑なことやってますけどね)
見ての通り、powerを計算した結果がどうこういう話は一切出てきません。(まあ、Cの場合、
この辺はコンパイル時に行われるので、値の評価をしようとしても出来ないんですけどね)

長々と書きましたが、言いたいことは、
「sizeof(main())の値は4(sizeof int)で正解」
ということです。

あとは余談ですが、

> sizeof(*func2) は、func2 が示す先が関数なのでエラー

って、ホント?確か、関数へのポインタの参照は例外的に関数へのポインタそのものに
なる仕様だったような…
ほら、gcc-2.95.3では通ったし…って、あれ?サイズ1?
た、試しに関数そのものを喰わせて…通ったし。-ansiオプションつきでも。
で、結果が同じく1。
g++ではどっちも関数喰わせちゃダメって怒られちゃったし。
…むう。私も相当なへっぽこだったようで。

---------- 以上、メール内容 ----------

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

私は悩みをリストアップし始めたが、そのあまりの長さにいやけがさし、何も考えないことにした。-- Robert C. Pike

読み込み中...