Search code examples
clanguage-lawyersizeofunions

Can a union be larger than the the largest member when the largest member is a primitive type?


Is there a possibility to make the size of a union larger than the largest member when the largest member is a integer, floating point type, _Complex type, _Atomic type, data pointer or function pointer and not a array, struct nor union*?

For example, can there be (or is there) a system where the following code will print 2 different sizes (assuming printing doesn't fail). If not, is there a other way to generate a union that is larger then the largest member even when the largest member is a "primitive type"**?

#include <complex.h>
#include <stdint.h>
#include <stdio.h>

#define MAX(a,b)       ( (a)>(b) ? (a) : (b) )
#define MAX4(a,b,c,d)  MAX( MAX( (a), (b) ), MAX( (c), (d) ) )

union Foo
{
  uintmax_t a;
  long double f;
  void (*fp)(void);
  void *data;
  double complex c;
};

int main(void)
{
  size_t l = MAX4( sizeof(void*), sizeof(void(*)(void)), sizeof(long double), sizeof(uintmax_t) );
  l = MAX( l, sizeof(double complex) );
  printf( "%zu %zu\n", sizeof(union Foo), l );
}

It (probably) doesn't change any productive code, it is just for curiosity.


Related but not the same question (use of a struct inside the union): sizeof union larger than expected. How does type alignment take place here? Size of Union changes with unexpected word alignment

*Are there any other classes of types i forgot?

**Is there a proper name for this types?


Solution

  • is there a other way to generate a union that is larger then the largest member even when the largest member is a "primitive type"?

    Yes, you can use _Alignas:

    union Foo {
        _Alignas(32) uintmax_t a;
        long double f;
        void (*fp)(void);
        void *data;
        double complex c;
    };
    
    //
    
    printf("%zu\n", sizeof(union Foo)); // 32
    

    Demo