C / CHAPTER 10

Function pointers and comparator contracts

Advanced

Pass behavior through an exact callable interface.

By the end of this chapter

  • Declare a function pointer parameter
  • Read a callback’s ownership contract
  • Write comparisons without subtraction overflow

The idea

A function pointer lets an algorithm call behavior supplied by its caller. Its type must match the function’s parameter and return contract; casting an incompatible function pointer does not make the actual call safe. State whether callbacks may retain pointers, mutate arguments, or access caller-owned context, because the type alone cannot express every lifetime rule.

The standard qsort callback receives pointers to elements and returns a negative, zero, or positive result according to their order. Subtracting two signed int values is a tempting comparison but can overflow. Comparing with relational operators and subtracting their boolean results avoids that overflow. qsort does not promise stable ordering of equal elements, so include a tie-breaker or choose a stable algorithm when that ordering matters.

C example
#include <stdio.h>
#include <stdlib.h>
int compare_int(const void *left, const void *right) {
  int a = *(const int *)left, b = *(const int *)right;
  return (a > b) - (a < b);
}
int main(void) {
  int values[] = {9, -2, 4};
  qsort(values, 3, sizeof values[0], compare_int);
  printf("%d %d %d\n", values[0], values[1], values[2]);
}
Result
-2 4 9

The comparator returns -1, 0, or 1 using safe relational results.

Try it yourself

Sort records by score and then by a unique numeric ID using comparisons that cannot overflow.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Why is (a > b) - (a < b) safer than a - b for int comparison?