我有一个比较的小程序
(1)sizeof, (2)numeric_limits :: digits, (3)和循环的结果
努力确保它们在任何C ++实现上报告关于“int类型”大小的相同内容。但是因为我不知道sizeof的内部结构,我不得不怀疑它是否只是报告numeric_limits :: digits。谢谢
答案 0 :(得分:3)
大多数编译器上的sizeof()
很可能导致编译器在其内部类型表中查找给定类型(或对象的类型),并将该类型的定义大小的文字插入到它生成的代码中。 这将在编译时发生,而不是运行时。
要回答评论中的问题,在C ++中没有任何语言定义的编译器内部访问权限(当然,除了sizeof()
本身之外)。我所知道的唯一类似的语言就是Ada,它提供了ASIS来编写独立于编译器的代码分析工具。
答案 1 :(得分:1)
sizeof
运算符是一个编译时构造,编译器通过该构造报告给定类型的实例将占用内存的大小(以字节为单位)。
很难给出一个通用的“这就是sizeof的工作方式”,因为它特定于每个编译器实现。在 general 中,虽然它的工作原理是计算类型中每个字段的大小,然后将它们加在一起,同时考虑对齐。
例如,这是一组合理的输出[1]
struct S1 {
int field1;
int field2;
};
struct S2 {
int field1;
bool field2;
int field3;
}
sizeof(S1) == 8
sizeof(S2) == 12;
许多编译器将S2
的大小报告为12而不是9的原因是它必须考虑对齐问题,因此插入3个字节以弥补field2
和{之间的差距{1}}
[1]注意:我说合理的不保证:)。 C编译在大小上有很大的灵活性,如果不知道你正在使用的编译器就几乎不可能陈述有关大小的细节
答案 2 :(得分:0)
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月)使代码双语。