实施C标准的附件K(边界检查接口)时,有以下要求:
可以通过将__STDC_WANT_LIB_EXT1__
定义为1
来声明本附件中指定的扩展名,并通过将{{1}定义为 not 来声明本扩展名1}}。
然后是本段:
在预处理翻译单元中,__ STDC_WANT_LIB_EXT1_ _的定义应完全相同,适用于K.3节中任何标头的所有包含。如果对__STDC_WANT_LIB_EXT1_ _的定义不同,则实现应发出诊断,就像使用预处理程序错误指令一样。
我想知道如何实现。我继续天真地编写了此代码(包含在每个受影响的标头中):
0
这(当然)由于多种原因而无效:
#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
的 value (前缀__STDC_WANT_LIB_EXT1__
会将符号作为字符串,通过symbol2value(...)将以#
作为字符串)。...但是,如果将其作为伪代码使用,它将展示其背后的逻辑。
我对这样复杂的预处理器业务并不熟悉,因为通常会告诉您不要使用宏魔术。 必须有一种方法来实现引用的要求;只是没有为我“点击”。
有什么想法吗?
要完成[mcve],请将上面的代码放入1
,并放在header.h
中:
testme.c
此应该会触发“差异值”错误消息。
答案 0 :(得分:4)
@HWalters确实使我走上了正轨:
#ifndef __STDC_WANT_LIB_EXT1__
#ifdef __STDC_WANT_LIB_EXT1_PREVIOUS__
#if __STDC_WANT_LIB_EXT1_PREVIOUS__ != -1
#error __STDC_WANT_LIB_EXT1__ undefined when it was defined earlier.
#endif
#else
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ -1
#endif
#else
#ifdef __STDC_WANT_LIB_EXT1_PREVIOUS__
#if __STDC_WANT_LIB_EXT1__ != __STDC_WANT_LIB_EXT1_PREVIOUS__
#error __STDC_WANT_LIB_EXT1__ redefined from previous value.
#endif
#else
#if __STDC_WANT_LIB_EXT1__ == 0
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ 0
#elif __STDC_WANT_LIB_EXT1__ == 1
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ 1
#else
/* Values other than 0,1 reserved for future use */
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ -2
#endif
#endif
#endif
“ thinko”是这一行:
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ __STDC_WANT_LIB_EXT1__
将“上一个”定义为另一个令牌的实际值可以使其工作。
不过,该解决方案也不是完美的-除0,1,undefined之外的所有“其他”值都集中到一个“上一个”值(-2)中,而标准字母表示 any 重新定义应发出诊断信息。