A binary search implementation for any datatype in C (continuation)
Code does not handle an array size of 0 (count == 0). Simple to fix

//size_t lo = 0, hi = count - 1, mid;
//while (lo &lt;= hi) {

size_t lo = 0, hi = count, mid;
while (lo &lt; hi) {
  hi--;


Potential UB.  Consider the below if mid == 0.  IMO, better to use a variable hi_plus_1 instead of hi and adjust code accordingly to avoid size_t underflow.

        hi = mid - 1;  // hi could become SIZE_MAX


Avoid losing const-ness.

const void *base
// char *base_ptr = (char *) base;
const char *base_ptr = (const char *) base;


binary_search.c is missing the include of binary_search.h.  This is important to maintain the consistency of the declaration and definition.

binary_search.h should include &lt;stdlib.h&gt; for size_t.

#include "binary_search.h"

void *binary_search(const void *x, const void *base, size_t count, size_t size,
    int (*compare)(const void *, const void *)) {
  const char *base_ptr = (const char *) base;
  size_t lo = 0, hi_plus1 = count;
  while (lo &lt; hi) {
    size_t mid = lo + (hi_plus1 - lo)/2;
    int result = (*compare)(base_ptr + mid * size, x);
    if (result == 0) {
      return base_ptr + mid * size;
    } else if (result &lt; 0) {
      lo = mid + 1;
    } else {
      hi_plus1 = mid;
    }
  }
  return NULL;
}




Test code

Problem specifier.  Use "%zu" for size_t.  The 2 below hint OP is not compiling with all warnings enabled.  Double-check that all warnings are enabled for prompt automatic feedback.

 size_t count, i;
 // scanf("%llu", &amp;count);
 scanf("%zu", &amp;count);

 for (i = 0; i &lt; count; i++) {
    // printf("%u : ", (i + 1));
    printf("%zu : ", (i + 1));


A size of 0 may cause for malloc() to return NULL and that is not an out-of-memory.

 a = malloc(count * size);
 // if (a == NULL) {
 if (a == NULL &amp;&amp; count &gt; 0) {
   printf("Error while trying to allocate memory.\n");


size = sizeof(double); lacks context.  Why sizeof(double)?  Certainly that is because that is the type a points to.  Then code that directly:

// size = sizeof(double);
size = sizeof *a;


For testing, useful to print the value sought and the value found.  Recommend %e for detail.  

printf("Value sought %e\n", x);
printf("Value found  %e\n", x, *result);
// or for sufficient detail
printf("Value sought %.*e\n", DBL_DECIMAL_DIG - 1, x);
printf("Value found  %.*e\n", DBL_DECIMAL_DIG - 1, *result);


With compare(), note that 0.0 will match -0.0.  If that is not desired, perhaps below.  Simplifications may be possible.

int compare(const void *a, const void *b) {
    const double *p = a;
    const double *q = b;
    if (*a &gt; *b) return 1;
    if (*a &lt; *b) return -1;
    if (isnan(*p)) return +1;
    if (isnan(*q)) return -1;

    // values are equal and not NaNs
    if (!signbit(*a) == !signbit(*b)) return 0;
    if (signbit(*a)) return -1;
    return 1;
}