views:

76

answers:

4

Given:

template <int N>
struct val2size
{
    char placeholder[N];
};

Is there any guarantee that sizeof(val2size<N>) == N?

+5  A: 

The only guarantee is that

sizeof(val2size<N>) >= N

There may be unnamed padding at the end of the struct. I don't think it's likely that there will be unnamed padding, but it's possible.

James McNellis
Thanks, so I suspected. Assuming that on practically any platform `sizeof(int)` is the natural word size (not sure if it's defined to be that way, though) is there a chance for padding in case it was an int array (with the size then being `N * sizeof(int)`)?
uj2
@uj2: From the AMD64 ABI http://www.x86-64.org/documentation/abi.pdf "An array uses the same alignment as its elements, except that a local or global array variable of length at least 16 bytes or a C99 variable-length array variable always has alignment of at least 16 bytes." It sounds like an array *subobject* will be exempt from this, but it's easy enough to try and see.
Potatoswatter
More generally speaking, it's somewhat reasonable for another ABI including vector types to extend such a requirement.
Potatoswatter
+3  A: 

No, James covers that. But you can get what you want with:

template <std::size_t N> // not an int, a negative value doesn't make sense
struct value_to_size
{
    typedef char type[N];
};

sizeof(value_to_size<N>::type) is guaranteed to be N. (This trick can be used to make a compile-time size-of array utility.)

GMan
Too bad I want to use `val2size` as a return type...
uj2
@uj2: Nothing in your question says anything about a return type. Why not ask a real question about a real problem, rather than a step?
GMan
@uj2: Nothing stops you from using `val2size` as a _return type_. But what are you trying to achieve by equating a type to a particular value? Compile time checks?
dirkgently
@GMan: You're correct. It is a partial question, although I felt it deserved to be asked separatly. The comment probablly wasn't too helpful though, it's a valid answer.
uj2
A: 

It depends on the size of N actually and whether that size of N char can be fit in a world align manner. If the memory of character array is world align ( 4 byte align for 32 bit and 8 byte align for 64 bit) then you will get sizeof==N or if not then it will add padding to make the memory allocated to be world align and in that case it will be >=N.

Anil Vishnoi
+1  A: 

By default, there is no guarantee because of possible padding. However, many compilers (at least VC++ and gcc) allow you to set the alignment of structures using a pragma, like this:

#pragma pack(push, 1)
template <int N>
struct val2size
{
    char placeholder[N];
};
#pragma pack(pop)

Setting the alignment to 1 essentially prevents any additional padding at the end of the structure.

casablanca
_Valid values are 1, 2, 4, 8, and 16. The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller._ From http://msdn.microsoft.com/en-us/library/2e70t5y1%28VS.80%29.aspx
dirkgently
Thanks for pointing that out, I actually meant 1. It's been a while since I used it.
casablanca