Reputation: 22133
I was thinking one of these:
#if sizeof(size_t) == 8
const size_t foo = 12345;
#elif sizeof(size_t) == 4
const size_t foo = 123;
#else
#error "Unsupported size_t size"
#endif
or
template <int S> class Foo { static const size_t foo = 0; };
template <> class Foo<8> { static const size_t foo = 12345; };
template <> class Foo<4> { static const size_t foo = 123; };
const size_t foo = Foo<sizeof(size_t)>::foo;
Also, how can I throw a compile-time error using the second method?
Upvotes: 1
Views: 377
Reputation: 28911
Use the type for the first and second member of a defined structure and get the offset of the second member to get the size of the first member (this assumes no padding between first and second member, the first member is guaranteed to have the same address as the structure).
#define ofs(s,m) (size_t)&(((s *)0)->m)
typedef struct S_{
size_t a; /* type to get the size of */
size_t b; /* make this same type as above */
}S;
int main()
{
size_t c;
c = ofs(S,b); /* get size of S.a */
return(0);
}
Upvotes: 0
Reputation: 145899
With g++
you can also use the following predefined macros:
__SIZEOF_SIZE_T__
__SIZEOF_INT__
__SIZEOF_LONG__
(and so on for the other types, see the documentation for a complete list).
For example:
#if __SIZEOF_SIZE_T__ == 8
const size_t foo = 12345;
#elif __SIZEOF_SIZE_T__ == 4
const size_t foo = 123;
#else
#error "Unsupported size_t size"
#endif
Upvotes: 1
Reputation: 437504
The solution with the class template is a good idiomatic way of doing this (the first alternative would also not work, so it's no contest between these two candidates).
To cause a compile-time error, simply do not define the template for all sizes:
template <int S> class Foo;
The compiler will then complain that the template is not defined for the offending value of sizeof(size_t)
.
It would also help to change the name from Foo
to something like Environment_Where_sizeof_int_is
-- you 'd get more immediately understandable compiler errors in practice.
Upvotes: 4