Domanda

Ho un piccolo programma che mette a confronto

(1) sizeof, (2) numeric_limits::cifre, (3) e i risultati di un ciclo

in uno sforzo per assicurarsi che essi segnalano la stessa cosa per quanto riguarda la dimensione di "int tipi" a qualsiasi implementazione di C++.Tuttavia, perché io non so i dettagli di sizeof, mi chiedo se è solo per il reporting di numeric_limits::cifre.Grazie

È stato utile?

Soluzione

La maggior parte probabile sizeof() sulla maggior parte dei compilatori fa sì che il compilatore sia il sembrare il tipo specificato (o il tipo dell'oggetto) nella sua tabella di tipo interno e inserire un letterale per la dimensione definita del tipo nel codice che genera. Ciò accadrebbe a tempo di compilazione , non runtime.

Per rispondere alla domanda nei commenti, non vi è alcun accesso definito dalla lingua agli interni del compilatore in C ++ (al di fuori di cose come sizeof() stesso, ovviamente).L'unico linguaggio simile che conosco che ti consente di fare cose del genere è ADA, che fornisce Asis Per scrivere strumenti di analisi del codice indipendenti dal compilatore.

Altri suggerimenti

Il sizeof l'operatore è un tempo di compilazione di costruire da cui il compilatore segnala la dimensione, in byte, di un'istanza di un certo tipo si occupano in memoria.

È difficile dare una generale "questo è come sizeof opere" risposta perché è specifico per ogni implementazione del compilatore.In generale se funziona calcolando la dimensione di ogni campo di un tipo e l'aggiunta di insieme mentre la contabilità per l'allineamento.

Per esempio, ecco una serie ragionevole di uscite [1]

struct S1 {
  int field1;
  int field2;
};

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

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

Il motivo per cui molti compilatori relazione la dimensione del S2 12 anziché 9 è che si deve tener conto dei problemi di allineamento e quindi inserire 3 byte per il divario tra field2 e field3

[1] Nota:Ho detto ragionevole non è garantita).C compila hanno un sacco di flessibilità in dimensioni ed è quasi impossibile stabilire le specifiche dimensioni senza conoscere il compilatore che si sta lavorando con

Non ci sono molti interni a sizeof;È un operatore incorporato che riporta la dimensione del suo operando (un'espressione o un tipo) in byte.

Il tuo codice è piuttosto complesso - e l'utilizzo di typeid mi lascia chiedersi ...

Ho un programma bilingue (scritto nel sottoinsieme C di C ++) che produce risposte come:

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

(Questo è stato prodotto da G ++ 4.6.0 su MacOS x 10.6.7 - una compilazione a 64 bit).Il codice che ho usato è:

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

Non ricordo esattamente il motivo per cui ho dovuto fare il pasticcio con __STDC_CONSTANT_MACROS e SPRINT() vs TPRINT(), ma sembrava essere ciò che era necessario (indietro nel marzo 2010) per rendere il codice bilingue.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top