Che cos'è una macro C / C ++ comune per determinare la dimensione di un membro della struttura?

StackOverflow https://stackoverflow.com/questions/1400660

  •  05-07-2019
  •  | 
  •  

Domanda

In C / C ++, come posso determinare la dimensione della variabile membro in una struttura senza la necessità di definire una variabile fittizia di quel tipo di struttura? Ecco un esempio di come farlo in modo sbagliato, ma mostra l'intento:

typedef struct myStruct {
  int x[10];
  int y;
} myStruct_t;

const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x);  // error

Per riferimento, questo dovrebbe essere come trovare la dimensione di 'x' se prima definisci una variabile fittizia:

myStruct_t dummyStructVar;

const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x);

Tuttavia, spero di evitare di dover creare una variabile fittizia solo per ottenere la dimensione di 'x'. Penso che ci sia un modo intelligente per rifondere 0 come myStruct_t per aiutare a trovare la dimensione della variabile membro 'x', ma è stato abbastanza a lungo che ho dimenticato i dettagli e non riesco a ottenere una buona ricerca su Google su questo . Sai?

Grazie!

È stato utile?

Soluzione

In C ++ (che è ciò che dicono i tag), la tua variabile "fittizia" il codice può essere sostituito con:

sizeof myStruct_t().x;

Non verrà creato alcun oggetto myStruct_t: il compilatore elabora solo il tipo statico dell'operando sizeof, non esegue l'espressione.

Funziona in C e in C ++ è meglio perché funziona anche per le classi senza un costruttore no-args accessibile:

sizeof ((myStruct_t *)0)->x

Altri suggerimenti

Sto usando la seguente macro:

#include <iostream>
#define DIM_FIELD(struct_type, field) (sizeof( ((struct_type*)0)->field ))
int main()
{
    struct ABC
    {
        int a;
        char b;
        double c;
    };
    std::cout << "ABC::a=" << DIM_FIELD(ABC, a) 
              << " ABC::c=" << DIM_FIELD(ABC, c) << std::endl;

    return 0;
}

Il trucco considera 0 come puntatore alla tua struttura. Questo problema viene risolto al momento della compilazione, quindi è sicuro.

Puoi farlo facilmente

sizeof(myStruct().x)

Dato che il parametro sizeof non viene mai eseguito, non creerai davvero quell'oggetto.

Ognuno di questi dovrebbe funzionare:

sizeof(myStruct_t().x;);

o

myStruct_t *tempPtr = NULL;
sizeof(tempPtr->x)

o

sizeof(((myStruct_t *)NULL)->x);

Poiché sizeof viene valutato in fase di compilazione, non in fase di esecuzione, non si verificheranno problemi a dereferenziare un puntatore NULL.

In C ++ 11, questo può essere fatto con sizeof (myStruct_t :: x) . C ++ 11 aggiunge anche std :: declval , che può essere utilizzato per questo (tra le altre cose):

#include <utility>
typedef struct myStruct {
  int x[10];
  int y;
} myStruct_t;

const std::size_t sizeof_MyStruct_x_normal = sizeof(myStruct_t::x);
const std::size_t sizeof_MyStruct_x_declval = sizeof(std::declval<myStruct_t>().x);

Dall'intestazione delle macro di utility:

#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))

invocato in questo modo:

FIELD_SIZE(myStruct_t, x);  
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top