2010-09-15 6 views
25

Es ist trivial, die Größe eines Feldes einer Struktur in C++ zu erhalten, wenn Sie eine Instanz der Struktur haben. Z.B. (Kompiliert):Kann ich die Größe eines Strukturfelds ohne das Erstellen einer Instanz der Struktur abrufen?

typedef struct Foo { 
    int bar; 
    bool baz; 
} Foo; 

// ... 

Foo s; 
StoreInSomething(s.bar, sizeof(s.bar)); // easy as pie 

Jetzt kann ich noch etwas tun, aber mit der Schnittstelle ich bin Umsetzung (I ein BOOL erhalten, dass der Zustand eines bestimmten Bit zeigt an, was in einem Bitfeld sein soll), I würde die Struktur nur erstellen, um die Größe des Datenelements zu erhalten. Gibt es eine Möglichkeit, dem Compiler anzuzeigen, dass er die Größe des Felds einer Struktur verwenden soll, ohne eine Instanz der Struktur zu erstellen? Es wäre die philosophische Äquivalent:

SetBit(bool val) { 
    StoreInSomething(
     BITFIELD_POSITION_CONSTANT, // position of bit being set 
     val,      // true = 1, false = 0 
     sizeof(Foo::bar));   // This is, of course, illegal. (The method I've been told I must use req's the size of the target field.) 
} 

Erstellen der Struktur auf dem Stapel sollte schnell und billig sein, aber ich vermute, ich werde in einem Code-Review für sie dinged bekommen, so dass ich bin auf der Suche nach einem besseren eine Art, die keine zusätzliche Wartungslast verursacht (wie #defines für Größen).

Antwort

34

Sie können einen Ausdruck verwenden, wie zum Beispiel:

sizeof Foo().bar 

als Argument sizeof nicht ausgewertet wird, nur seine Art, nicht nur vorübergehend ist eigentlich erstellt.

bearbeiten

Wenn Foo nicht konstruierbar Standard (im Gegensatz zu Ihrem Beispiel), dann würden Sie einen anderen Ausdruck, wie eine Beteiligung einen Zeiger verwenden. (Danke an Mike Seymour)

sizeof ((Foo*)0)->bar 
+0

Interessant. In Anbetracht dessen, dass das OP nach C++ fragt, gibt es eine Möglichkeit, dies auch in C zu tun? –

+5

Solange 'Foo' ist standardmäßig konstruierbar. Andernfalls benötigen Sie einige Dummy-Konstruktorargumente oder "sizeof ((Foo *) 0) -> bar". @Dan: Die Zeigerversion wird auch in C funktionieren. –

+1

+1: mein Gehirn explodiert gerade –

5
typedef struct Foo { 
    typedef BarType int; 
    BarType bar; 
    bool baz; 
} Foo; 

...

sizeof(Foo::BarType) 
2

Sie können sizeof mit einem Zeiger auf die Struktur verwenden. Betrachten wir etwa wie folgt:

#include <stdio.h> 

typedef struct Foo { 
    char   cbar; 
    short  sbar; 
    int   bar; 
    bool   baz; 
    long long llbar; 
} Foo; 




int main (void) 
{ 
    struct Foo *p_foo = 0; 

    printf("Size of cbar: %d\n", sizeof(p_foo->cbar)); 
    printf("Size of sbar: %d\n", sizeof(p_foo->sbar)); 
    printf("Size of bar: %d\n", sizeof(p_foo->bar)); 
    printf("Size of baz: %d\n", sizeof(p_foo->baz)); 
    printf("Size of llbar: %d\n", sizeof(p_foo->llbar)); 
} 

Welche Ergebnisse wie gibt:

163> size.exe 
Size of cbar: 1 
Size of sbar: 2 
Size of bar: 4 
Size of baz: 1 
Size of llbar: 8