sizeof如何适用于int类型?

时间:2011-05-16 20:46:04

标签: c++ int sizeof numeric-limits

我有一个比较的小程序

(1)sizeof, (2)numeric_limits :: digits, (3)和循环的结果

努力确保它们在任何C ++实现上报告关于“int类型”大小的相同内容。但是因为我不知道sizeof的内部结构,我不得不怀疑它是否只是报告numeric_limits :: digits。谢谢

3 个答案:

答案 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_MACROSSPRINT()TPRINT()进行混淆,但这似乎是需要的(早在2010年3月)使代码双语。