468,740 Members | 1,922 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,740 developers. It's quick & easy.

Structure size check at compile time

Hi

I'm porting some C++ code to new platforms and have some 1-byte aligned
structures which need a specific size. Since datatypes can vary on different
platforms (which I found out the hard way since longs are not the same size
on win64 and linux x64) I would like to do a check at compile time to make
sure things are correct. This will ease future work.

Is it possible to do something like the following at preprocessing stage:

typedef struct _aaa
{
UINT32 a;
UINT16 b;
}aaa;

#if sizeof(aaa) != (4 + 2)
#error "Wrong settings for this platform"
#endif

The compiler seems to fail no matter which platform I use. I know I can do
this at runtime but it's not useful code so I rather not have it done at
runtime. The only alternative is to enable it as a runtime check when
compiling in debug mode.

Thanks in advance.

-- John
Jan 5 '06 #1
4 6925
John Smith wrote:
Hi
Is it possible to do something like the following at preprocessing stage:
Not at preprocessing, but at compile time.
typedef struct _aaa
{
UINT32 a;
UINT16 b;
}aaa;
Isn't this same as
struct aaa {
UNIT32 a;
UINT16 b;
};

Also, UNIT32 and UNIT16 are not std C++ types . So I believe that they
are platform dependent typedefs or new type definitions.

#if sizeof(aaa) != (4 + 2)
This doesnot work because sizeof is a _compile-time_ operator, and it
is being used at preprocessing time
#error "Wrong settings for this platform"
#endif


Something on the lines of CTAssert (Ref. Modern C++ Design)

template<int i> class CorrectSize;
template<> class CorrectSize<6> {
};

int main()
{
CorrectSize<sizeof(aaa)>(); // Gives compile time error if
sizeof(aaa) is anything other than 6
}

Jan 5 '06 #2
John Smith wrote:
Hi

I'm porting some C++ code to new platforms and have some 1-byte aligned
structures which need a specific size. Since datatypes can vary on different
platforms (which I found out the hard way since longs are not the same size
on win64 and linux x64) I would like to do a check at compile time to make
sure things are correct. This will ease future work.

Is it possible to do something like the following at preprocessing stage:

typedef struct _aaa
{
UINT32 a;
UINT16 b;
}aaa;

#if sizeof(aaa) != (4 + 2)
#error "Wrong settings for this platform"
#endif

The compiler seems to fail no matter which platform I use. I know I can do
this at runtime but it's not useful code so I rather not have it done at
runtime. The only alternative is to enable it as a runtime check when
compiling in debug mode.

Thanks in advance.

-- John


Does your *preprocessor* really evaluate the size of objects? I bet
that's your problem right there. At best, the result of a "sizeof"
isn't known until the compiler runs, and at worst, it isn't known until
run time. Assuming that your struct's size can be evaluated at
compile-time and your compiler is suffiently smart, just put something
like this at the begining of your program (warning: not tested):

if (sizeof(aaa) != (4 + 2))
{
cerr << "Wrong settings for this platform" << endl;
abort();
}

On platforms where the size of the struct really is 6, the compiler will
detect that the condition is always false and optimize it out
completely. On platforms where it isn't, the compiler might even
optimize out the rest of the program.

If you must check this at compile time, I'd suggest putting a check into
your build system. GNU autoconf, for instance, will allow you to
compile and run a trivial program that checks the size of your struct,
and trigger an alert if it's not the size you expected before attempting
to compile your program.

Rennie deGraaf
Jan 5 '06 #3
you may want to do something like this:

//////////////////////////////////////////////////
template<int i> class ThrowError;
template<> class ThrowError<0>
{
public:
enum {val = 0};
};

template<class T, int expected_size>
class CheckSize
{
enum { value = (sizeof(T) == expected_size) ? 0 : 1};
enum { errval = ThrowError<value>::val };
};

/////////////////////////////////////////////////////
class Test
{
UINT32 i;
};

int main()
{
CheckSize<Test, 4>(); // compiles ok, sizeof Test is 4 bytes
CheckSize<Test, 8>(); // compilation, error, size is incorrect
return 0;
}

Jan 5 '06 #4
Rennie deGraaf wrote:
Does your *preprocessor* really evaluate the size of objects? I bet
that's your problem right there. At best, the result of a "sizeof"
isn't known until the compiler runs, and at worst, it isn't known until
run time.


sizeof is always evaluated at compile time, but not by the preprocessor.

Jan 5 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Luca | last post: by
13 posts views Thread by Amarendra | last post: by
6 posts views Thread by Laurent | last post: by
2 posts views Thread by Mike | last post: by
6 posts views Thread by AlabiChin | last post: by
56 posts views Thread by Bruce. | last post: by
6 posts views Thread by carles | last post: by
1 post views Thread by CARIGAR | last post: by
xarzu
2 posts views Thread by xarzu | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.