#include <stddef.h>
#include <stdio.h>
#include <mpi.h>

typedef struct _S {
  unsigned short f0[1];
  unsigned char  f1[1];
} S;

int main(int argc, char *argv[]) {
  int blocklengths[2];
  MPI_Aint displacements[2];
  MPI_Datatype types[2];
  MPI_Datatype newtype;
  MPI_Aint lb, extent;
  MPI_Aint true_lb;

  MPI_Init(&argc,&argv);
  blocklengths[0] = 1; displacements[0] = offsetof(S, f0); types[0] = MPI_UNSIGNED_SHORT;
  blocklengths[1] = 1; displacements[1] = offsetof(S, f1); types[1] = MPI_UNSIGNED_CHAR;

#ifndef CASE
#define CASE 4
#endif
  switch (CASE) {
  case 0:
    break;
  case 1:
    MPI_Type_dup(types[0], &types[0]);
    MPI_Type_dup(types[1], &types[1]);
    break;
  case 2:
    MPI_Type_contiguous(1, types[0], &types[0]);
    MPI_Type_contiguous(1, types[1], &types[1]);
    break;
  case 3:
    {
      int b[1] = {1}; MPI_Aint d[1] = {0};
      MPI_Type_create_struct(1, b, d, &types[0], &types[0]); 
      MPI_Type_create_struct(1, b, d, &types[1], &types[1]);
    }
    break;
  case 4:
    {
      int n[1] = {1}, s[1] = {0};
      MPI_Type_create_subarray(1, n, n, s, MPI_ORDER_C, types[0], &types[0]);
      MPI_Type_create_subarray(1, n, n, s, MPI_ORDER_C, types[1], &types[1]);
    }
    break;
  case 5:
    MPI_Type_create_resized(types[0], 0, (MPI_Aint)sizeof(short), &types[0]);
    break;
  }

  MPI_Type_create_struct(2, blocklengths, displacements, types, &newtype);
  MPI_Type_get_extent(newtype, &lb, &extent);
  printf("c-sizeof=%d  mpi-extent=%d\n", (int)sizeof(S), (int)extent);

  if (types[0] != MPI_UNSIGNED_SHORT) MPI_Type_free(&types[0]);
  if (types[1] != MPI_UNSIGNED_CHAR)  MPI_Type_free(&types[1]);

  MPI_Type_free(&newtype);
  MPI_Finalize();
  return 0;
}
