How to ensure that two types are the same size?

In my code I want to make sure sizeof(a) == sizeof(b) .

The first approach was to let the preprocessor perform the check:

 #if (sizeof(a) != sizeof(b)) # error sizes don't match #endif 

which does not compile due to fatal error C1017: invalid integer constant expression . Good. Understand.

Next attempt:

 if(sizeof(a) != sizeof(b)){ printf("sizes don't match\n"); return -1; } 

This results in a warning: warning C4127: conditional expression is constant .

Now i'm stuck. Is there a way without warning and without errors to make sure that the two structures a and b are the same size?


Edit: The compiler is Visual Studio 2005, the warning level is set to 4.

+6
source share
4 answers

Bad array size

  // 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)];

Bad compile time arithmetic

In C ++, it is guaranteed that these constant expressions are evaluated by the compiler at compile time, and I believe that this is true 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 (for fun only)

  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 it until the compiler is 100% happy.

+6
source

The first case is explicitly prohibited according to the #if documentation:

An expression cannot use sizeof or a type cast operator.

As for the warning, you can either ignore it (because you know that your code is ok), disable it using #pragma , or simply deduce the condition from 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 attracted some attention, here are a few ways to achieve this using #pragma warning :

 #pragma warning (push) #pragma warning (disable: 4127) if(sizeof(a) != sizeof(b)){ #pragma warning (pop) // ... 

Pop, obviously, could be done further down the code. Another option might be:

 #pragma warning (disable: 4127) if(sizeof(a) != sizeof(b)){ #pragma warning (default: 4127) 

Which will return a warning without pressing or popping up.

In any case, this code looks ugly. IMO, just using bool to get the result of comparing sizeof (as my first snippet shows) would be the cleanest solution.

+2
source
 #include <stdio.h> struct tag { int a; }; main() { struct tag a,b; if(sizeof(a) != sizeof(b)) printf("not"); else printf("same"); } 

these programs work fine without warning ... !!!

0
source

Although you can play hide and seek with the compiler and hide the constant in places that the compiler does not see, this is not the best way to suppress warnings. This will make the code seem unclear to the next person who will support it.

If you need to suppress compiler warnings, be honest with that. In Visual Studio 2005, you are best off using pragmas:

http://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

0
source

Source: https://habr.com/ru/post/898646/


All Articles