确保预处理器定义不会更改值

时间:2019-05-06 05:50:23

标签: c c-preprocessor

实施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

应该会触发“差异值”错误消息。

1 个答案:

答案 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 重新定义应发出诊断信息。