Explicit non-null pointers in C

Browsing this thread on Stack Overflow, I learnt about a lesser known feature of C which allows you to explicitly declare that a particular array must contain at least some number of elements. Consider the following piece of unsafe code:

typedef struct {
  int foo;
  int bar;
  int qux;
} important_t;

void safelyPrintImportant(important_t *imp) {
  printf("%d %d %d\n", imp->foo, imp->bar, imp->qux);
}

If the goal were to be nasty, I'd just have to try and poison this function with a NULL pointer and the application would cause a segfault. Actually, for a long time I thought that code written in C was destined to be vulnerable to these kinds of mistakes.

However, as I learnt today, as of C99 you can actually hint the compiler that the pointer must be non-null. How? C has support for function arguments to contain the static keyword inside the array descriptor part, which specifies the minimum number of elements which the array should be. Here's an example from the thread:

float round_float_to_4(float inputval[static 4]);

This actually means the argument array, inputval, must be at least 4 elements large. This language feature helps us because arrays and pointers share special equivalence in C, so we can fix up our vulnerable function above like so (full working example):

#include <stdio.h>

typedef struct {
  int foo;
  int bar;
  int qux;
} important_t;

void safelyPrintImportant(important_t imp[static 1]) {
  printf("%d %d %d\n", imp->foo, imp->bar, imp->qux);
}

int main() {
  static important_t counting = {1, 2, 3};
  safelyPrintImportant(&counting);
  return 0;
}

But if we now try and insert some nasty code:

safelyPrintImportant(NULL);
// warning: warning: null passed to a callee which requires a non-null argument [-Wnonnull]

Unfourtunately, it's not all that smart. We can circumvent both gcc and clang quite easily by just assigning a local to NULL and passing it:

important_t *counting = NULL;
safelyPrintImportant(counting);

It does offer some protection against incorrect NULLing of non-optional pointer parameters, though.