Я знаю, что в ISO C нет возможности для этого (пока), и что в GNU C есть __attribute__((nonnull)) для параметров функции и __attribute__((returns_nonnull)) для возвращаемых значений. Но есть ли какое-либо расширение для локальных переменных в GCC или Clang?





Да, в clang есть _Nonnull, чтобы дать компилятору подсказку, что вы не будете устанавливать его NULL:
#include <stdio.h>
int main(void) {
void* _Nonnull x = NULL;
}
Он предназначен исключительно для подсказок по оптимизации и не мешает вам установить для него значение NULL.
Квалификатор допускающего значение null
_Nonnullуказывает, что значение null не является значимым значением для значения типа указателя_Nonnull.
Я знаю, что в ISO C нет возможности для этого.
Для параметров функции он уже 25 лет назад:
void func (int ptr[static 1])
Подробнее см. Что делает ключевое слово static в C?
Вы правы, но меня конкретно интересовали локальные переменные. Ключевое слово static нельзя использовать для void *, возвращаемого значения или локальной переменной.
@Харит Ну, вы можете делать разные уродливые трюки, такие как #define func(x) actual_func(x, &(int){0}) ... int* actual_func (int some_param, int not_null[static 1]) { int* ret_val = not_null; int* some_local = not_null; ... return ret_val; } Супер уродливо, но, по крайней мере, компилятору следует позволить выполнять оптимизацию, предполагая, что ни один указатель не инициализирован как нулевой указатель. Если вы присваиваете им значения из внешних функций и т. д., это уже не так.
C23 имеет (будет иметь) 7 стандартных атрибутов —
deprecated,fallthrough,maybe_unused,nodiscard,noreturn,unsequencedиreproducible. Они не включают в себя какие-либо ненулевые атрибуты. Он допускает использование «префиксов атрибутов», специфичных для реализации, которые могут использовать такие обозначения, как[[gcc::nonnull]]. Если компилятор не распознает атрибут, он должен его игнорировать. См. §6.7.12 Атрибуты в черновых версиях стандарта C23. Примечание: ссылка на черновик от сентября 2022 года. Более новые черновики предназначены для C26 или заблокированы.