2016-10-23 12:18:18 UTC
I'd like to propose extending the syntax for pointer parameter declarations to allow following construct:
int f(int * static p);
Which should be equivalent to
int f(int p[static 1]);
For incomplete types, the static qualified pointer means that the pointer argument shall not be null.
Additionally, functions specified within the standard, for which passing a null pointer invokes undefined behavior shall have their pointer parameters revised to include the new static qualifier.
C99 introduced the ability to specify a minimum argument array length to be honored by the caller, like so:
int max(int arr[static 1]);
The same revision also introduced the ability to qualify pointer parameters written in array form, like so:
int swap(int a[restrict static 1], int b[restrict static 1]);
Specifying 1 as the minimum array length, effectively means that the pointer shall be valid and non-null. It's not possible to convey this information while using the pointer parameter syntax.
Additionally, following constructs with parameters pointing to incomplete types are invalid:
time_t f(struct tm[static 1]);
memmove(void[static 1], void[static 1], size_t);
And no standard way of specifying that the pointers in the previous listing are non-null exists.
GNU C solves this with __attribute__((nonnull(...))). Examples of usage can be found in both the GNU and BSD libc standard headers.
The Clang, GNU and Intel C compilers all provide basic diagnostics for __attribute__((nonnull)). Clang also provides warnings for when it can deduce the array argument is too small.
This proposal would allow specifying the non-null constraint directly in code, to be seen by programmer as well as static analyzer.
No existing code is affected. New code willing to make use of the feature, needs only to add a static after the *, which will always be possible, unlike the array syntax which doesn't work for incomplete types.
int max(int * static arr]);
int swap(int * restrict static a, int * restrict static b);
time_t f(struct tm * static);
memmove(void * static, void * static, size_t);
Thanks for reading. Comments requested. If there is a good reception, I will look into drafting a formal proposal and the official channels through which to submit it.