Skip to content

Instantly share code, notes, and snippets.

@gvanem
Last active September 6, 2017 16:31
Show Gist options
  • Select an option

  • Save gvanem/4eb51651a033e883e7919f88e11a7e34 to your computer and use it in GitHub Desktop.

Select an option

Save gvanem/4eb51651a033e883e7919f88e11a7e34 to your computer and use it in GitHub Desktop.
/*
* A small sample shows undefined behaviour in 'qsort()'
* when all elements *comparing on* are equal. I.e. all
* the array elements are not necessarily equal; only the one we
* care about. It seems a 'swap()' operation is performed anyway (?)
*
* Compile:
* c:\> clang -Wall -o qsort-undefined.exe qsort-undefined.c
* or
* c:\> gcc -Wall -o qsort-undefined.exe qsort-undefined.c
* or
* c:\> cl -nologo -W3 -Fe./qsort-undefined.exe qsort-undefined.c
*
* Output:
* c:\> qsort-undefined.exe
* qsort-undefined.c(43): Before qsort():
* qsort-undefined.c(45): ip: 7.7.7.7 metric: 10
* qsort-undefined.c(45): ip: 8.8.8.8 metric: 10
* qsort-undefined.c(45): ip: 9.9.9.9 metric: 10
* qsort-undefined.c(49): After qsort():
* qsort-undefined.c(51): ip: 8.8.8.8 metric: 10
* qsort-undefined.c(51): ip: 9.9.9.9 metric: 10
* qsort-undefined.c(51): ip: 7.7.7.7 metric: 10
*/
#include <stdio.h>
#include <stdlib.h>
#define TRACE(fmt, ...) do { \
printf ("%s(%u): " fmt, \
__FILE__, __LINE__, \
## __VA_ARGS__); \
} while (0)
typedef struct {
unsigned metric; /* The metric we sort them by. */
char ip[20];
} Address;
static int compareAddresses (const void *arg1,
const void *arg2)
{
const Address *left = arg1;
const Address *right = arg2;
if (left->metric < right->metric)
return -1;
if (left->metric > right->metric)
return 1;
return 0;
}
int main (void)
{
Address addresses[] = {
{ 10, "7.7.7.7" },
{ 10, "8.8.8.8" },
{ 10, "9.9.9.9" },
};
int i, num = sizeof(addresses) / sizeof(addresses[0]);
TRACE ("Before qsort():\n");
for (i = 0; i < num; i++)
TRACE (" ip: %15s metric: %u\n", addresses[i].ip, addresses[i].metric);
qsort (&addresses, num, sizeof(addresses[0]), compareAddresses);
TRACE ("After qsort():\n");
for (i = 0; i < num; i++)
TRACE (" ip: %15s metric: %u\n", addresses[i].ip, addresses[i].metric);
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment