17

I know that sizeof is a compile-time calculation, but this seems odd to me: The compiler can take either a type name, or an expression (from which it deduces the type). But how do you identify a type within a class? It seems the only way is to pass an expression, which seems pretty clunky.

struct X { int x; };
int main() {
    // return sizeof(X::x); // doesn't work
    return sizeof(X()::x); // works, and requires X to be default-constructible
}
4
  • 11
    Support for sizeof(X::x) is included in C++0x (cf. open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html). Commented Jan 25, 2010 at 0:25
  • @James +1 at your comment. My answer(deleted) should have been a comment actually, because Tom didn't mention C++0x. Maybe he wants it in C++98 :) Commented Jan 25, 2010 at 0:29
  • Yes, my question is about C++98. However, even if I build with -std=c++0x, it doesn't work (GCC 4.3.2). Are there any compiler implementations that do support it yet? Commented Jan 25, 2010 at 0:49
  • 1
    Intel C++ Compiler 11.1 does not support it. GCC 4.4 includes support for it (per gcc.gnu.org/projects/cxx0x.html; I don't have an installation of GCC to test it). Commented Jan 25, 2010 at 20:05

3 Answers 3

27

An alternate method works without needing a default constructor:

return sizeof(((X *)0)->x);

You can wrap this in a macro so it reads better:

#define member_sizeof(T,F) sizeof(((T *)0)->F)
Sign up to request clarification or add additional context in comments.

5 Comments

AFAIK, dereferencing a NULL pointer is undefined behavior. Does that rule apply in this case also?
@AraK: I don't think so: "The operand [of sizeof] is either an expression, which is not evaluated, or a parenthesized type-id" (5.3.3/1; emphasis mine).
The NULL pointer is never dereferenced. This is a compile-time operation. It's just merely to get the compiler to do The Right Thing(tm).
Isn't that 'return sizeof...' the same as the offsetof?
@tommieb75: The sizeof x is the number of bytes occupied by the x member. The offsetof x is the number of bytes x is offset from the start of its enclosing structure X.
10

Here is a solution without the nasty null pointer dereferencing ;)

struct X { int x; };

template<class T> T make(); // note it's only a declaration

int main()
{
    std::cout << sizeof(make<X>().x) << std::endl;
}

1 Comment

Couldn't you just say extern T fakeT; sizeof(fakeT.x); ?
0

What about offsetof? Have a look here. Also have a look here, which combines both sizeof and offsetof into a macro.

Hope this helps.

1 Comment

Doesn't help, because the compiler (while required to order the elements of the structure in the declared order) is free to pad them as it deems necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.