Reputation: 7550
If I have a class that contains only compile-time constants, for example,
class A {
static const int x = 1;
static const int y = 2;
static const int z = 3;
};
I believe it's the case that, so long as the address of the constants is not taken, they can (will?) be replaced at compile time where they are used and will not take up any space in the executable (as constants that is, obviously the numbers themselves are going to have to show up). If this is the case can/will the class also be optimized out? And, will this change if something inherits from class A
, but still only uses the constants themselves and does not take their addresses?
Oh, and assuming, in the non-inheritance version, that the class is not actually used itself anywhere apart from as a means to access the constants.
Thanks.
Upvotes: 3
Views: 553
Reputation: 224119
It's been given a size just because even object of such a class need to have a size. (For starters, if two such objects were members of another object, would they have distinct addresses if you form member pointers to them?) When this class is used as a base class, it will benefit from the empty base class optimization and be reduced to size 0. In fact, this
#include <iostream>
struct A {};
struct B { char x; };
struct C : public A, public B {};
int main()
{
std::cout << sizeof(A) << '\n';
std::cout << sizeof(B) << '\n';
std::cout << sizeof(C) << '\n';
return 0;
}
prints
1 1 1
for me, so A
doesn't contribute anything to the size of C
, which seems to support my interpretation that A
's size of 1
is artificial.
Upvotes: 1
Reputation: 34423
No, the static const int member will will not have any space allocated for them, as they are evaluated as compile time constants.
As for size of the class object (i.e. sizeof(A)
), this is not relevant unless you are creating instances of the class A - which you explicitly said you are not.
That said, perhaps you could use namespace instead to make your intention a bit clearer? Unless you are using it for something like template traits, it seems you are abusing class to do the job namespaces are intended for.
Upvotes: 3
Reputation: 882028
I believe that every type must have a sizeof
of at least 1 (partly to ensure instance of that type get different addresses in an array for example).
Section 5.3.3 of the C++0x draft standard is where this is dictated:
When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array. The size of a most derived class shall be greater than zero.
They shouldn't affect the size of an instance (since they're static) but they will probably need to be stored in the executable somewhere since you need to be able to use the address-of operator on them. Whether they can be optimised out of existence depends entirely on the compiler and whether it can tell they're not being de-referenced. Enumerations are probably a better tool to use in this particular case.
However, three integers in an application is unlikely to cause a problem.
Upvotes: 1
Reputation: 355167
It doesn't matter whether those variables are const
; they are static
, so they won't affect the size of the class anyway.
sizeof(A)
cannot be zero, so if you create an instance of A
it has to be at least one byte in size. However, having A
as a base class does not necessarily increase the size of a derived class because "base class sub-objects may have zero size" (C++03 §1.8/5).
Upvotes: 7