clanguage-lawyernull-pointerc23

Is there an equivalent of __attribute__((nonnull)) in C23?


Several compiler vendors have implemented a non standard extension __attribute__((nonnull)) to specify that a pointer must not be a null pointer.

C99 introduced a new syntax to specify that a function argument must point to the first element of an array with at least a given number of elements, so passing a null pointer as argument s to a function foo declared as void foo(int s[static 1]) would be a constraint violation that the compiler can detect and report. Yet this syntax is restricted to function arguments so it cannot be used for function return values nor variable or aggregate member definitions. Furthermore passing a pointer one past the last element of an array to foo would still be a constraint violation albeit not a null pointer. void foo(int s[static 0]) does not seem to be allowed by the C Standard.

There does not seem to be an attribute [[nonnull]] in section 6.7.12 Attributes of the latest C23 draft (the only standard attributes are [[deprecated]], [[fallthrough]], [[maybe_unused]], [[nodiscard]], [[noreturn]], [[_Noreturn]], [[reproducible]] and [[unsequenced]].

A similar but different question was asked before: Is __attribute__((nonnull)) standardized in C
The response is no but it does not answer my question.

Is there an alternative way in Standard C to specify that a pointer should not be null?
Was there a proposal in this direction for C23?


Solution

  • No there is no such attribute in C23.

    The only thing new related to null is nullptr and nullptr_t. nullptr being a new keyword guaranteed to be a null pointer constant, much like NULL and also defined in stddef.h.

    You may however declare a function with a returned value as [[nodiscard]] to force the caller to handle the return value and not just ignore it, which may be handy if they are expected to check if a function returned null or not.

    Is there an alternative way in Standard C to specify that a pointer should not be null?

    As you mention, the only way so far is by using array parameters to a function and specifying the array dimension as static. At least modern versions of gcc and clang has some checks built in to support this.

    Was there a proposal in this direction for C23?

    There is a related proposal from earlier this year (not voted into C23) here: n3089.

    As I understand it, C23 will not accept further features as per last summer of 2022, so this will not get included even if voted for in favour. The bureaucratic wheels have grinded beyond the reach of the ISO C WG and C23 has now reached bureaucratic box number 40.00, as seen here: https://www.iso.org/standard/82075.html.