sizeof は int 型に対してどのように機能しますか?
-
14-11-2019 - |
質問
比較する小さなプログラムがあります
(1)sizeof、(2)numeric_limits :: digits、(3)およびループの結果
あらゆる C++ 実装の「int 型」のサイズに関して、すべてが同じことを報告するようにするための取り組みです。ただし、sizeof の内部についてはわからないので、単に numeric_limits::digitals を報告しているだけなのかどうか疑問に思います。ありがとう
解決
最も可能性が高い sizeof()
ほとんどのコンパイラーでは、コンパイラーは内部型テーブルで指定された型 (またはオブジェクトの型) を検索し、その型の定義されたサイズのリテラルを生成するコードに挿入します。 これはコンパイル時に発生します, 、ランタイムではありません。
コメントの質問に答えると、C++ ではコンパイラの内部への言語定義のアクセスはありません ( sizeof()
もちろんそれ自体です)。私が知っている、そのようなことを可能にする同様の言語は Ada だけです。 そのまま コンパイラに依存しないコード分析ツールを作成するためのものです。
他のヒント
sizeof
演算子は、コンパイラが指定されたタイプのインスタンスがメモリ内で占有するサイズをバイト単位で報告するコンパイル時構文です。
一般的な「これは、それはすべてのコンパイラ実装に固有のものであるため、SizeOf Worksの仕組みです」回答を与えるのは難しいです。 General は、タイプのすべてのフィールドのサイズを計算し、アライメントを説明しながらそれらを追加することによって機能します。
次に、ここに合理的な出力セット[1]
.
struct S1 {
int field1;
int field2;
};
struct S2 {
int field1;
bool field2;
int field3;
}
sizeof(S1) == 8
sizeof(S2) == 12;
多くのコンパイラは、9とは対照的に、S2
のサイズを12として報告します。
[1]注:私は合理的なものは保証されていません:)。Cコンパイルはサイズの柔軟性がたくさんあり、それはあなたが働いているコンパイラを知らずにサイズに関する述べることはほとんど不可能です。
内部的な情報はあまりありません sizeof
;これは、オペランド (式または型) のサイズをバイト単位で報告する組み込み演算子です。
あなたのコードはかなり複雑です - そして、 typeid
疑問に思ってしまいます...
次のような答えを生成するバイリンガル プログラム (C++ の C サブセットで書かれた) があります。
1 = sizeof(char)
1 = sizeof(unsigned char)
2 = sizeof(short)
2 = sizeof(unsigned short)
4 = sizeof(int)
4 = sizeof(unsigned int)
8 = sizeof(long)
8 = sizeof(unsigned long)
4 = sizeof(float)
8 = sizeof(double)
16 = sizeof(long double)
8 = sizeof(size_t)
8 = sizeof(ptrdiff_t)
8 = sizeof(time_t)
8 = sizeof(void *)
8 = sizeof(char *)
8 = sizeof(short *)
8 = sizeof(int *)
8 = sizeof(long *)
8 = sizeof(float *)
8 = sizeof(double *)
8 = sizeof(int (*)(void))
8 = sizeof(double (*)(void))
8 = sizeof(char *(*)(void))
1 = sizeof(struct { char a; })
2 = sizeof(struct { short a; })
4 = sizeof(struct { int a; })
8 = sizeof(struct { long a; })
4 = sizeof(struct { float a; })
8 = sizeof(struct { double a; })
16 = sizeof(struct { char a; double b; })
16 = sizeof(struct { short a; double b; })
16 = sizeof(struct { long a; double b; })
4 = sizeof(struct { char a; char b; short c; })
16 = sizeof(struct { char a; char b; long c; })
4 = sizeof(struct { short a; short b; })
6 = sizeof(struct { char a[3]; char b[3]; })
8 = sizeof(struct { char a[3]; char b[3]; short c; })
16 = sizeof(struct { long double a; })
32 = sizeof(struct { char a; long double b; })
(これは、MacOS X 10.6.7 上の G++ 4.6.0 によって生成されました (64 ビット コンパイル)。私が使用したコードは次のとおりです。
#ifdef __cplusplus
#define __STDC_CONSTANT_MACROS
#endif /* __cplusplus */
#include <stdio.h>
#include <time.h>
#include <stddef.h>
#if __STDC_VERSION__ >= 199901L || HAVE_INTTYPES_H
#include <inttypes.h>
#endif /* __STDC_VERSION__ */
/* Using the simple C code in SPRINT() for structures leads to complaints from G++ */
/* Using the code in TPRINT() for pointers to functions leads to other complaints */
#define TPRINT(x) do { typedef x y; printf("%2u = sizeof(" #x ")\n", (unsigned int)sizeof(y)); } while (0)
#define SPRINT(x) printf("%2u = sizeof(" #x ")\n", (unsigned int)sizeof(x))
int main(void)
{
/* Basic Types */
SPRINT(char);
SPRINT(unsigned char);
SPRINT(short);
SPRINT(unsigned short);
SPRINT(int);
SPRINT(unsigned int);
SPRINT(long);
SPRINT(unsigned long);
SPRINT(float);
SPRINT(double);
SPRINT(long double);
SPRINT(size_t);
SPRINT(ptrdiff_t);
SPRINT(time_t);
/* Fancy integers */
#if __STDC_VERSION__ >= 199901L || HAVE_LONG_LONG
SPRINT(long long);
SPRINT(unsigned long long);
#endif /* __STDC_VERSION__ || HAVE_LONG_LONG */
#if __STDC_VERSION__ >= 199901L || HAVE_INTTYPES_H
SPRINT(uintmax_t);
#ifdef INT8_MAX
SPRINT(int8_t);
#endif
#ifdef INT16_MAX
SPRINT(int16_t);
#endif
#ifdef INT32_MAX
SPRINT(int32_t);
#endif
#ifdef INT64_MAX
SPRINT(int64_t);
#endif
#ifdef INT128_MAX
SPRINT(int128_t);
#endif
SPRINT(int_least8_t);
SPRINT(int_least16_t);
SPRINT(int_least32_t);
SPRINT(int_least64_t);
SPRINT(int_fast8_t);
SPRINT(int_fast16_t);
SPRINT(int_fast32_t);
SPRINT(int_fast64_t);
SPRINT(uintptr_t);
#endif /* __STDC_VERSION__ || HAVE_INTTYPES_H */
/* Pointers */
SPRINT(void *);
SPRINT(char *);
SPRINT(short *);
SPRINT(int *);
SPRINT(long *);
SPRINT(float *);
SPRINT(double *);
/* Pointers to functions */
SPRINT(int (*)(void));
SPRINT(double (*)(void));
SPRINT(char *(*)(void));
/* Structures */
TPRINT(struct { char a; });
TPRINT(struct { short a; });
TPRINT(struct { int a; });
TPRINT(struct { long a; });
TPRINT(struct { float a; });
TPRINT(struct { double a; });
TPRINT(struct { char a; double b; });
TPRINT(struct { short a; double b; });
TPRINT(struct { long a; double b; });
TPRINT(struct { char a; char b; short c; });
TPRINT(struct { char a; char b; long c; });
TPRINT(struct { short a; short b; });
TPRINT(struct { char a[3]; char b[3]; });
TPRINT(struct { char a[3]; char b[3]; short c; });
TPRINT(struct { long double a; });
TPRINT(struct { char a; long double b; });
#if __STDC_VERSION__ >= 199901L || HAVE_LONG_LONG
TPRINT(struct { char a; long long b; });
#endif /* __STDC_VERSION__ */
#if __STDC_VERSION__ >= 199901L || HAVE_INTTYPES_H
TPRINT(struct { char a; uintmax_t b; });
#endif /* __STDC_VERSION__ || HAVE_INTTYPES_H */
return(0);
}
なぜいじる必要があったのか正確には覚えていない __STDC_CONSTANT_MACROS
そして SPRINT()
対 TPRINT()
, 、しかし、それはコードをバイリンガルにするために必要なものだったようです (2010 年 3 月に遡ります)。