tags:

views:

108

answers:

3

It's trivial to get the size of a struct's field in C++ if you have an instance of the struct. E.g. (uncompiled):

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

// ...

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

Now I can still do something like this, but with the interface I'm implementing (I get a BOOL that indicates what the state of a specific bit in a bitfield should be), I'd be creating the struct solely to get the size of the data member. Is there a way to indicate to the compiler that it should use the size of a struct's field without creating an instance of the struct? It would be the philosophical equivalent of:

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

Creating the struct on the stack should be fast and cheap, but I suspect I'll get dinged for it in a code review, so I'm looking for a better way that doesn't introduce an add'l maintenance burden (such as #defines for sizes).

+1  A: 
typedef struct Foo { 
    typedef BarType int;
    BarType bar; 
    bool baz; 
} Foo;

...

sizeof(Foo::BarType)
Binary Worrier
+9  A: 

You can use an expression such as:

sizeof Foo().bar

As the argument of sizeof isn't evaluated, only its type, no temporary is actually created.

Edit

If Foo wasn't default constructible (unlike your example), you'd have to use a different expression such as one involving a pointer. (Thanks to Mike Seymour)

sizeof ((Foo*)0)->bar
Charles Bailey
Interesting. Realizing that the OP is asking about C++, is there a way of doing this that works in C too?
Dan Moulding
As long as `Foo` is default constructible. Otherwise, you'll need some dummy constructor arguments, or `sizeof ((Foo*)0)->bar`. @Dan: The pointer version will work in C, too.
Mike Seymour
+1: my brain just exploded
John Dibling
This is quality. :) _Exactly_ what I was looking for!
Greg D
@Mike Seymour: good point, yours is more flexible.
Charles Bailey
@John Dibling: Mine too, grey matter everywhere . . . *well obviously not much in my case*
Binary Worrier
Greg D
@Mike: I actually should have known that the pointer method would work, because I frequently use that trick in GDB when I want to know a member's size. Never thought about actually compiling code using that, though. Thanks!
Dan Moulding
The `offsetof` macro is usually implemented using a similar (and even more brain-exploding) technique.
jamesdlin
A: 

You can use sizeof of with a pointer to the structure. Consider something like the following:

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

Which gives results such as:

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