In my code, I want to ensure that sizeof(a) == sizeof(b)
.
First approach was to let the preprocessor do the checking:
#if (sizeof(a) != sizeof(b))
# error sizes don't match
#endif
which doesn't compile because of fatal error C1017: invalid integer constant expression
. Okay. Understand.
Next try:
if(sizeof(a) != sizeof(b)){
printf("sizes don't match\n");
return -1;
}
Which results in a warning: warning C4127: conditional expression is constant
.
Now, I'm stuck. Is there a warning-and-error-free way to make sure that the two structs a
and b
have the same size?
Edit: Compiler is Visual Studio 2005, Warning level is set to 4.
// make sure sizeof(a) == sizeof(b): int size_must_match[sizeof(a) == sizeof(b)]; // will fail if sizeof(a) == sizeof(b) evaluates to 0 // might produce warning: 'size_must_match' is not used // to suppress "'size_must_match' is not used", try: size_must_match[0]; // might produce warning: "statement has no effect"
or
typedef int size_must_match[sizeof(a) == sizeof(b)];
In C++ is guaranteed that these constant expressions are evaluated by the compiler at compile-time, and I believe the same holds in C:
// make sure sizeof(a) == sizeof(b): 1 / (sizeof(a) == sizeof(b)); // might produce warning: "statement has no effect" int size_must_match = 1 / (sizeof(a) == sizeof(b)); // might produce warning: 'size_must_match' is unused assert (1 / (sizeof(a) == sizeof(b))); // very silly way to use assert!
switch (0) { // compiler might complain that the // controlling expression is constant case 0: case sizeof(a) == sizeof(b): ; // nothing to do }
You get the idea. Just play around with this until the compiler is 100 % happy.
The first case is explicitly forbidden according to #if
documentation:
The expression cannot use sizeof or a type-cast operator.
As for the warning, you can either ignore it (because you know your code is ok), disable it using a #pragma
, or just take the condition out of the if
:
bool sizeMatch = (sizeof(a) == sizeof(b));
if (!sizeMatch){
printf("sizes don't match\n");
return -1;
}
Edit: since disabling the error seems to have drawn some attention, here are a couple of ways to achieve that using #pragma warning
:
#pragma warning (push)
#pragma warning (disable: 4127)
if(sizeof(a) != sizeof(b)){
#pragma warning (pop)
// ...
The pop could obviously be done further down the code. Another option could be:
#pragma warning (disable: 4127)
if(sizeof(a) != sizeof(b)){
#pragma warning (default: 4127)
Which will turn the warning back on without pushing and popping.
Either way, this code does look ugly. IMO, just using a bool
to get the result of the sizeof
comparison (as my first snippet shows) would be the cleanest solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With