
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))

struct tag1 {
	int m1;
	int m2;
	int m3;
};

struct tag2 {
	int m1;
	int m2;
};

int offset;	/* int member offset for comparison */

main()
{
	int cmpstia(const void *, const void *);
	struct tag1 st1[] = {
		{1, 2, 3},
		{3, 1, 2},
		{2, 3, 1}
	};
	struct tag2 st2[] = {
		{7, 9},
		{5, 3},
		{2, 6},
		{6, 1}
	};
	int i;

/* sort st1 on m1 */

	offset = offsetof(struct tag1, m1);
	qsort(&st1[0], NUMELEM(st1), sizeof(struct tag1), cmpstia);

	for (i = 0; i < NUMELEM(st1); ++i)
		printf("st1[%d]: %d, %d, %d\n", i, st1[i].m1,
			st1[i].m2, st1[i].m3);

/* sort st1 on m3 */

	offset = offsetof(struct tag1, m3);
	qsort(&st1[0], NUMELEM(st1), sizeof(struct tag1), cmpstia);

	putchar('\n');
	for (i = 0; i < NUMELEM(st1); ++i)
		printf("st1[%d]: %d, %d, %d\n", i, st1[i].m1,
			st1[i].m2, st1[i].m3);

/* sort st2 on m2 */

	offset = offsetof(struct tag2, m2);
	qsort(&st2[0], NUMELEM(st2), sizeof(struct tag2), cmpstia);

	putchar('\n');
	for (i = 0; i < NUMELEM(st2); ++i)
		printf("st2[%d]: %d, %d\n", i, st2[i].m1, st2[i].m2);

	return 0;
}

/* compare ints in ascending order */

int cmpstia(const void *pe1, const void *pe2)
{
	return *(int *)((char *)pe1 + offset) - 
		*(int *)((char *)pe2 + offset);
}

st1[0]: 1, 2, 3
st1[1]: 2, 3, 1
st1[2]: 3, 1, 2

st1[0]: 2, 3, 1
st1[1]: 3, 1, 2
st1[2]: 1, 2, 3

st2[0]: 6, 1
st2[1]: 5, 3
st2[2]: 2, 6
st2[3]: 7, 9

