Pergunta

Eu tenho um pequeno programa que compara

(1) Sizeof, (2) numeric_limits :: dígitos, (3) e os resultados de um loop

em um esforço para garantir que todos relatem a mesma coisa em relação ao tamanho dos "tipos int" em qualquer implementação C++.No entanto, como não sei sobre os detalhes internos de sizeof, tenho que me perguntar se ele está apenas relatando numeric_limits::digits.Obrigado

Foi útil?

Solução

Provavelmente sizeof() na maioria dos compiladores faz com que o compilador pareça o tipo dado (ou o tipo de objeto) em sua tabela de tipo interno e insira um literal para o tamanho definido do tipo no código que gera. Isso aconteceria no tempo de compilação , não tempo de execução.

Para responder a pergunta nos comentários, não há acesso definido por idioma aos internos do compilador em C ++ (fora das coisas como a própria geragem, é claro).A única linguagem semelhante que eu conheço que permite que você faça coisas assim é Ada, que fornece asis Para escrever ferramentas de análise de código independente do compilador.

Outras dicas

O sizeof operador é uma construção de tempo de compilação pela qual o compilador relata o tamanho, em bytes, que uma instância de um determinado tipo ocupará na memória.

É difícil dar uma resposta geral "é assim que sizeof funciona" porque é específica para cada implementação de compilador.Em em geral embora funcione calculando o tamanho de cada campo de um tipo e somando-os enquanto contabiliza o alinhamento.

Por exemplo, aqui está um conjunto razoável de resultados [1]

struct S1 {
  int field1;
  int field2;
};

struct S2 {
  int field1;
  bool field2;
  int field3;
}

sizeof(S1) == 8
sizeof(S2) == 12;

A razão pela qual muitos compiladores relatarão o tamanho do S2 como 12 em oposição a 9 é que ele deve levar em conta problemas de alinhamento e, portanto, inserir 3 bytes para compensar a lacuna entre field2 e field3

[1] Nota:Eu disse razoável, não garantido :).As compilações C têm muita flexibilidade em tamanhos e é quase impossível especificar detalhes sobre tamanhos sem conhecer o compilador com o qual você está trabalhando

Não há muitos internos para sizeof;é um operador integrado que informa o tamanho do seu operando (uma expressão ou um tipo) em bytes.

Seu código é bastante complexo - e usando typeid me deixa pensando...

Tenho um programa bilíngue (escrito no subconjunto C de C++) que produz respostas como:

 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; })

(Isso foi produzido pelo G++ 4.6.0 no MacOS X 10.6.7 - uma compilação de 64 bits).O código que usei é:

#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);
}

Não me lembro exatamente por que tive que mexer com __STDC_CONSTANT_MACROS e SPRINT() contra TPRINT(), mas parecia ser isso que era necessário (em março de 2010) para tornar o código bilíngue.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top