4

Given:

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

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

uj2
  • 2,255
  • 2
  • 21
  • 32
  • 1
    You can get the same thing from `boost::array` or C++0x `std::array`. – Potatoswatter Sep 05 '10 at 20:15
  • Note that most of the answers assumed you were speaking of ONLY containing an array, and no other members. The more members there are, the more likely it is that the size of the object is superior to the sum of their individual sizes. – Matthieu M. Sep 06 '10 at 06:52

4 Answers4

6

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
  • 348,265
  • 75
  • 913
  • 977
  • 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 Sep 05 '10 at 20:07
  • @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 Sep 05 '10 at 20:18
  • More generally speaking, it's somewhat reasonable for another ABI including vector types to extend such a requirement. – Potatoswatter Sep 05 '10 at 20:25
3

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

Community
  • 1
  • 1
GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • @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? – GManNickG Sep 05 '10 at 20:12
  • @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 Sep 05 '10 at 20:18
  • 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 Sep 05 '10 at 20:27
1

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
  • 69,683
  • 7
  • 133
  • 150
  • 1
    _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 Sep 05 '10 at 20:15
  • Thanks for pointing that out, I actually meant 1. It's been a while since I used it. – casablanca Sep 05 '10 at 20:17
0

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,352
  • 3
  • 18
  • 25