□ sizeofは関数でなく演算子
sizeof は、変数や、型が占めるバイト数を求めるという
かなり特殊用途の存在で、
もし他の言語ならば組込関数とでも
分類されるものになっていたかもしれませんが、C言語では
(単項の)演算子
です。
演算子というと +,-,*,/ などの記号ばかりを思い浮かべてしまいますが
関数みたいに見えても演算子なんです。
関数のような表記をよくしますが変数のサイズを求めるのならば
sizeof tbl
のように記述してもかまわないわけです。
が、型のサイズを求めるときは
sizeof(int)
のように必ず()がいりますし、もちろん見やすさ等を考慮するならば
sizeof(tbl)
のように必ず () を付けたほうが、無難にも
思います。
この機能は、Cの関数定義で作ることは不可能なので組み込みの
演算子として提供しているのでしょうが、このような関数的なもので
コンパイラにとって特殊なのはsizeofだけで
main()やprintf()等は特殊処理してるように思えるかもしれないけれど、
Cコンパイラにとっては、ただの関数
ということは忘れないでやってください。
(もっとも、人間にとって特殊でバグの要因にもなるためオプション
指定によっては普通の関数定義の範囲を超えた機能を提供するコンパイラも
中にはあるでしょう)
あと、sizeof が求められるサイズは、あくまで、コンパイル時に値が決定できるもの、
ソース上できちっとサイズ情報が確定できるものだけであって、
malloc等で動的に確保した領域のサイズなどを sizeofで求めることはできません。
char *tbl;のとき tbl = malloc(0x1000); をしたあと sizeof(tbl) としても、
0x1000 などという値になるわけではないです。
動作としては sizeof(char*)をしたのと同じ値になるだけですので、
文法的には正しいのでエラーにもならないわけです(だから勘違いしてるとマズイことになります)。
コンパイラにとってmalloc(とか標準ライブラリ関数と呼ばれるもの)も、他のユーザの書いた関数と
同様なものでしかなく、また sizeof もあくまで、定数値を直接記述するのを肩代わりするだけで
式や関数的な働きをすることはないわけです。
結局、動的にメモリを利用するときは、定数ラベルを用意するか変数で
管理するかは事情しだいだけど sizeof は利用できないということです。