Зачем "программировать" директивами в заголовочных файлах
В последнее время я просматривал довольно много репозиториев 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 шт):
Как и сказали в комментариях, это для переносимости и совместимости кода на разных платформах и с языком С, а также постоянно выходят обновы, чтобы идти в ногу со временем(которые тоже добавляют свои стандарты и соглашения, но из-за того, что язык "старый, объемный" обязательно да возникнет конфликт, вот и выкручиваются так).
Зачем "программировать" директивами
Бывают разные причины.
#ifdef _UCRT
нужна чтобы выбирать C runtime (стандартную библиотеку С): либо старую msvcrt.dll
(если макроса нет), либо новую ucrtbase.dll
(если он есть).
Про #ifdef _POSIX_
не совсем уверен. Выглядит так, что макрос определен везде кроме винды, а хедер должен быть совместим с разными ОС.
#ifndef _FILE_DEFINED
- это какая-то вариация на тему include guard (но обычно он один на хедер, а почему тут сделали для отдельной структуры - опять же непонятно).