Sizeof演算子を実装しようとしました。このようにしています。
#define my_sizeof(x) ((&x + 1) - &x)
しかし、どちらのデータ型でも結果は常に「1」になります。
私はそれのためにそれをググった..そして私はコードを見つけたtypecasted
#define my_size(x) ((char *)(&x + 1) - (char *)&x)
そして、コードが型キャストされている場合、コードは機能します。理由はわかりません。
それはまた働いています
#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x)
型キャストされた場合と型キャストされなかった場合の動作を誰かが説明できますか?
前もって感謝します..
ポインター減算の結果は、バイトではなくelementsにあります。したがって、最初の式は、定義により_1
_に評価されます。
これはさておき、マクロでは括弧を使うべきです:
_#define my_sizeof(x) ((&x + 1) - &x)
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)
_
そうしないと、式でmy_sizeof()
を使用しようとするとエラーが発生する可能性があります。
sizeof
演算子はC(およびC++)言語仕様の一部であり、コンパイラー(フロントエンド)内に実装されています。他のC構文で実装する方法はありません( typeof のようなGCC拡張機能を使用しない限り)。これは、副作用を起こすことなく、型または式をオペランドとして受け入れることができるためです(例:sizeof((i>1)?i:(1/i))
はクラッシュしませんi==0
がマクロmy_sizeof
はゼロ除算でクラッシュします)。 Cコーディングのガイドライン 、および wikipedia も参照してください。
C ポインタ演算 を理解する必要があります。たとえば、 この質問 。ポインタの違いは、バイトではなく要素で表現されます。
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)
このmy_sizeof()
マクロは、次の場合には機能しません。
sizeof 1
-4バイト(4バイトのint
のプラットフォームの場合)my_sizeof(1)
-まったくコンパイルされません。
sizeof (int)
-4バイト(4バイトのプラットフォームの場合int
)my_sizeof(int)
-コードをまったくコンパイルしません。
変数に対してのみ機能します。 int
、float
、char
などのデータ型、2
、3.4
、'A'
などのリテラル、またはa+b
などの右辺値式では機能しません。またはfoo()
。
しかし、いずれのデータ型でも常に結果は「1」となる
はい、それがポインター演算の仕組みです。ポイントされているタイプの単位で機能します。したがって、char *
にキャストすると、char
の単位が機能します。
_#define my_sizeof(x) ((&x + 1) - &x)
_
_&x
_は、プログラムで宣言された変数(double xとしましょう)のアドレスを与え、1でインクリメントすると、タイプxの次の変数を格納できるアドレスを与えます(ここではaddr_of(x) + 8
、 doubleのサイズは8バイトです)。
違いは、x
のタイプの変数をいくつのメモリに格納できるかという結果を与えます。これは、タイプxに対して明らかに1になります(1でインクリメントし、その差を取ることは、完了)。
_#define my_size(x) ((char *)(&x + 1) - (char *)&x)
_
それを_char*
_に型キャストし、その差をとると、指定されたメモリ空間に格納できるchar
型の変数の数(差)がわかります。各char
は1バイトのメモリしか必要としないため、(メモリの量)/ 1は、マクロに渡される変数のタイプの連続する2つのメモリ位置間のバイト数、したがってメモリの量を示しますタイプx
の変数に必要です。
しかし、このマクロにリテラルを渡してそのサイズを知ることはできません。
私は昨日これを検索し、このマクロを見つけました:
#define mysizeof(X) ((X*)0+1)
これは、Xを1回だけ展開し(x ++のような式の二重評価としてエラーは発生しません)、現在まで問題なく機能します。