Зачем "программировать" директивами в заголовочных файлах

В последнее время я просматривал довольно много репозиториев C'ишного кода,

И я не понимаю зачем нужно "программировать" директивами

Даже стандартные библиотеки

Например:

// фрагмент из <stdio.h>

#ifndef _FILE_DEFINED
  struct _iobuf {
#ifdef _UCRT
    void *_Placeholder;
#else
    char *_ptr;
    int _cnt;
    char *_base;
    int _flag;
    int _file;
    int _charbuf;
    int _bufsiz;
    char *_tmpfname;
#endif
  };
  typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif

#ifdef _POSIX_
#define _P_tmpdir "/"
#define _wP_tmpdir L"/"
#else
#define _P_tmpdir "\\"
#define _wP_tmpdir L"\\"
#endif

#ifdef _UCRT
#define L_tmpnam 260
#else
#define L_tmpnam (sizeof(_P_tmpdir) + 12)
#endif

Причем, как я понял, там разные header'ы для разных систем

(например там есть #include <_mingw_off_t.h> в винде, и он не обёрнут в #if, #ifdef или что-то ещё)

Можете объяснить зачем вообще это нужно?


Ответы (2 шт):

Автор решения: Den

Как и сказали в комментариях, это для переносимости и совместимости кода на разных платформах и с языком С, а также постоянно выходят обновы, чтобы идти в ногу со временем(которые тоже добавляют свои стандарты и соглашения, но из-за того, что язык "старый, объемный" обязательно да возникнет конфликт, вот и выкручиваются так).

→ Ссылка
Автор решения: HolyBlackCat

Зачем "программировать" директивами

Бывают разные причины.

#ifdef _UCRT нужна чтобы выбирать C runtime (стандартную библиотеку С): либо старую msvcrt.dll (если макроса нет), либо новую ucrtbase.dll (если он есть).

Про #ifdef _POSIX_ не совсем уверен. Выглядит так, что макрос определен везде кроме винды, а хедер должен быть совместим с разными ОС.

#ifndef _FILE_DEFINED - это какая-то вариация на тему include guard (но обычно он один на хедер, а почему тут сделали для отдельной структуры - опять же непонятно).

→ Ссылка