При реализации Приложения K стандарта C (Интерфейсы проверки границ) существует следующее требование:
Расширения, указанные в этом приложении, могут быть "запрошены" для объявления путем определения от __STDC_WANT_LIB_EXT1__
до 1
, а для запроса не должны быть объявлены путем определения того, что 0
.
Тогда есть этот абзац:
В блоке преобразования предварительной обработки __STDC_WANT_LIB_EXT1_ _ должно быть идентично определено для всех включений любых заголовков из подпункта K.3. Если __STDC_WANT_LIB_EXT1_ _ определяется по-разному для любого такого включения, реализация должна выдать диагностику, как если бы использовалась директива об ошибке препроцессора.
Интересно, как это реализовать. Я пошел дальше и наивно написал это (будет включено в каждый затронутый заголовок):
#ifndef __STDC_WANT_LIB_EXT1__
#ifdef __STDC_WANT_LIB_EXT1_PREVIOUS__
#error __STDC_WANT_LIB_EXT1__ undefined when it was defined previously.
#endif
#else
#ifdef __STDC_WANT_LIB_EXT1_PREVIOUS__
#if __STDC_WANT_LIB_EXT1__ != __STDC_WANT_LIB_EXT1_PREVIOUS__
#error __STDC_WANT_LIB_EXT1__ defined to different value from previous include.
#endif
#else
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ __STDC_WANT_LIB_EXT1__
#endif
#endif
Это (конечно) не работает по разным причинам:
- Не учитывается случай, когда
__STDC_WANT_LIB_EXT1__
не определен для первого включения, но определен для второго (который также должен быть пойман с помощью #error
)
-
#define
не принимает значение из __STDC_WANT_LIB_EXT1__
(префикс #
будет принимать символ в виде строки, при проходе по symbol2value (...) будет приниматься 1
в качестве строки ).
- ...
... но если взять псевдокод, он демонстрирует логику, стоящую за ним.
Я не так хорошо разбираюсь в более сложных делах препроцессоров, как это, так как обычно вам говорят держаться подальше от макромагиков. Должен быть способ выполнить указанное требование; это просто не "щелкает" для меня.
Есть идеи?
Чтобы завершить [mcve], поместите приведенный выше код в header.h
, и это в testme.c
:
#define __STDC_WANT_LIB_EXT1__ 0
#include "header.h"
#define __STDC_WANT_LIB_EXT1__ 1
#include "header.h"
int main() {}
Это должно вызвать сообщение об ошибке «другое значение».