C++ sizeof如何处理int类型?

C++ sizeof如何处理int类型?,c++,int,sizeof,numeric-limits,C++,Int,Sizeof,Numeric Limits,我有一个比较 (1) sizeof, (2) 数字限制::数字, (3) 以及循环的结果 试图确保它们对任何C++实现的“int类型”的大小都报告相同的内容。然而,因为我不知道sizeof的内部结构,我不得不怀疑它是否只是报告数字限制::数字。多亏了运算符sizeof是一个编译时构造,编译器通过它报告给定类型的实例将在内存中占用的大小(以字节为单位) 很难给出一个通用的“sizeof就是这样工作的”答案,因为它特定于每个编译器实现。在常规中虽然它通过计算类型的每个字段的大小并将它们相加,同时考虑

我有一个比较

(1) sizeof, (2) 数字限制::数字, (3) 以及循环的结果


试图确保它们对任何C++实现的“int类型”的大小都报告相同的内容。然而,因为我不知道sizeof的内部结构,我不得不怀疑它是否只是报告数字限制::数字。多亏了运算符

sizeof
是一个编译时构造,编译器通过它报告给定类型的实例将在内存中占用的大小(以字节为单位)

很难给出一个通用的“sizeof就是这样工作的”答案,因为它特定于每个编译器实现。在常规中虽然它通过计算类型的每个字段的大小并将它们相加,同时考虑对齐来工作

例如,这里有一组合理的输出[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
field3
之间的差距

[1] 注:我说的合理不保证:)。C编译器在大小上有很大的灵活性,几乎不可能在不知道正在使用的编译器的情况下说明大小的具体信息。在大多数编译器上,很可能是
sizeof()
导致编译器查看给定的类型(或对象的类型)在它的内部类型表中,并将该类型的定义大小的文本插入到它生成的代码中这将发生在编译时,而不是运行时


回答注释中的问题,在C++中没有任何语言定义的编译器内部访问(当然是在代码之外> SIEZOFF()之外的代码<当然是代码>本身。我所知道的唯一一种类似的语言是Ada,它提供了编写独立于编译器的代码分析工具。

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);
}
\ifdef\uuucplusplus
#定义\uu STDC\u常量\u宏
#endif/*\uuu cplusplus*/
#包括
#包括
#包括
#如果uu STDC uu>=199901L | |具有u INTTYPES uh
#包括
#endif/*\uuuu STDC\u版本\uuuu*/
/*对结构使用SPRINT()中的简单C代码会引起G++的抱怨*/
/*使用TPRINT()中的代码作为函数指针会导致其他问题*/
#定义TPRINT(x)do{typedef x y;printf(“%2u=sizeof(“#x”)\n”,(unsigned int)sizeof(y));}而(0)
#定义SPRINT(x)printf(“%2u=sizeof(“#x”)\n),(未签名int)sizeof(x))
内部主(空)
{
/*基本类型*/
SPRINT(char);
SPRINT(未签名字符);
短跑;
短跑(无符号短跑);
SPRINT(int);
SPRINT(无符号整数);
短跑(长距离);
短跑(无符号长距离);
短跑(漂浮);
短跑(双人);
短跑(长双);
SPRINT(size\u t);
斯普林特;
冲刺(时间);
/*花式整数*/
#如果u STDC uu>=199901L | |有u LONG u LONG
短跑(长距离);
SPRINT(未签名的long-long);
#endif/*uu STDC_uu124;版本u124; |有u LONG 124;*/
#如果uu STDC uu>=199901L | |具有u INTTYPES uh
SPRINT(uintmax_t);
#ifdef INT8_MAX
短跑(国际);
#恩迪夫
#ifdef INT16_最大值
斯普林特(国际16日);
#恩迪夫
#ifdef INT32_MAX
斯普林特(int32_t);
#恩迪夫
#ifdef INT64_MAX
SPRINT(int64_t);
#恩迪夫
#ifdef INT128_最大值
SPRINT(int128_t);
#恩迪夫
短跑(至少8分钟);
短跑(至少16分钟);
短跑(至少32分钟);
短跑(至少64分钟);
短跑(国际快跑8分);
短跑(国际快跑);
短跑(int_fast32_t);
短跑(国际快速跑);
斯普林特;
#endif/*uuuuu STDC_uu124;版本uu124;具有u INTTYPES_H*/
/*指针*/
冲刺(无效*);
SPRINT(char*);
短跑(短*);
SPRINT(int*);
短跑(长*);
短跑(浮球*);
短跑(双人*);
/*指向函数的指针*/
SPRINT(int(*)(void));
冲刺(双(*)(无效));
SPRINT(char*(*)(void));
/*结构*/
TPRINT(struct{char a;});
TPRINT(struct{short a;});
TPRINT(struct{inta;});
TPRINT(struct{long a;});
TPRINT(struct{float a;});
TPRINT(结构{double a;});
TPRINT(结构{char a;double b;});
TPRINT(struct{short a;double b;});
TPRINT(结构{long a;double b;});
TPRINT(结构{char a;char b;short c;});
TPRINT(结构{char a;char b;long c;});
TPRINT(结构{short a;short b;});
TPRINT(结构{char a[3];char b[3];});
TPRINT(struct{char a[3];char b[3];short c;});
TPRINT(结构{long double a;});
TPRINT(结构{chara;长双精度b;});
#如果u STDC uu>=199901L | |有u LONG u LONG
TPRINT(结构{char a;long-long b;});
#endif/*\uuuu STDC\u版本\uuuu*/
#如果uu STDC uu>=199901L | |具有u INTTYPES uh
TPRINT(结构{char a;uintmax_t b;});
#endif/*uuuuu STDC_uu124;版本uu124;具有u INTTYPES_H*/
返回(0);
}

我记不清为什么我要处理
\uu STDC\u CONSTANT\u宏
SPRINT()
vs
TPRINT()
,但这似乎是使代码双语化所需要的(回到2010年3月)。

你知道我如何在内部类型表上手动查找值吗?谢谢。@Chris:对于类型
T
sizeof(T)
产生特定的数据位。一个不那么迂腐的答案是,除非您的特定编译器允许,否则结果可能取决于您设置的标志