【问题标题】:Do we have c99 subflags我们有 c99 子标志吗
【发布时间】:2013-06-03 06:15:08
【问题描述】:

是否为 -std=c99 提供了子选项,以便我可以通过这些子选项并避免通过 -std=c99?

例如:

int main()
{
    for(int i=0;i<10;i++)
    {
        i++;
    }
    return 0;
}

我会通过传递任何子选项来用 gcc 编译这段代码。

$ gcc -sub-option-for-c99 a.c

谢谢

编辑:我只想从 C99 中选择一个特性,同时将编译器的其余部分保持在 C89(或其他)模式。

【问题讨论】:

  • 什么是子选项?
  • 我完全不明白 - -std=c99 的子选项是什么?还有为什么要避开路过-std=c99(或许你想用std=gnu99?)
  • @Prof.Falken 是 c99 的最小版本,它解决了 c99 提供的特定结构。
  • 所以您只想从 C99 中选择一个特性,同时将编译器的其余部分保持在 C89(或其他)模式下?
  • C99 对功能的子设置没有太多规定(基本上没有子设置)。 C11 确实对此有一些规定。但是,实现的细节往往由实现控制,而不是程序员可以通过诸如-std=c11-std=gnu11 之类的整体开关来更改的东西。这是说“”的冗长方式。

标签: c gcc compiler-construction c99


【解决方案1】:

C99 对功能的子设置没有太多规定(基本上没有子设置)。 C11 确实对此有一些规定。但是,实现的细节往往由实现控制,而不是程序员可以通过诸如-std=c11-std=gnu11 之类的整体开关来更改的东西。这是说“No”的冗长方式。

C11 中的子设置示例:附件 K(以前的 TR 24731-1)边界检查接口。

程序可以通过定义__STDC_WANT_LIB_EXT1__ 来表明它想要使用这些设施,但是如果实现本身没有定义__STDC_LIB_EXT1__,这将无济于事。

来自 ISO/IEC 9899:2011 的更完整的子设置列表(Corr.1 应用于 __STDC_LIB_EXT1__ 的值):

6.10.8.3 条件特征宏

¶1 以下宏名称由实现有条件地定义:

  • __STDC_ANALYZABLE__ 整数常量 1,用于表示符合 附录 L(可分析性)中的规范。
  • __STDC_IEC_559__ 整数常量 1,用于表示符合 附录 F 中的规范(IEC 60559 浮点运算)。
  • __STDC_IEC_559_COMPLEX__整数常量1,意在表示 遵守附录 G 中的规范(IEC 60559 兼容复杂 算术)。
  • __STDC_LIB_EXT1__整数常量201112L,意在表示支持 对于附件 K(边界检查接口)中定义的扩展。179)
  • __STDC_NO_ATOMICS__ 整数常量 1,用于表示 实现不支持原子类型(包括_Atomic 类型限定符)和 &lt;stdatomic.h&gt; 标头。
  • __STDC_NO_COMPLEX__ 整数常量 1,用于表示 实现不支持复杂类型或 标题。
  • __STDC_NO_THREADS__ 整数常量 1,用于表示 实现不支持 &lt;threads.h&gt; 标头。
  • __STDC_NO_VLA__ 整数常量 1,用于表示 实现不支持可变长度数组或可变 修改类型。

¶2 定义 __STDC_NO_COMPLEX__ 的实现不应定义 __STDC_IEC_559_COMPLEX__.

179) 目的是保持long int 类型的整数常量,随着 本国际标准的每次修订。

有关相关信息,另请参阅6.10.8 预定义宏名称部分。

请注意,这些宏是由实现定义或不定义的,具体取决于它支持或不支持的内容。如果您尝试自己设置它们,那将没有任何区别;它们旨在让实现与您进行通信,反之亦然。


ISO/IEC 9899:1999 §6.10.8 预定义的宏名称

¶2 以下宏名称由实现有条件地定义:

  • __STDC_IEC_559__ 整数常量 1,用于表示符合 附录 F 中的规范(IEC 60559 浮点运算)。
  • __STDC_IEC_559_COMPLEX__整数常量1,意在表示 遵守资料性附录 G 中的规范(IEC 60559 兼容的复数算法)。
  • __STDC_ISO_10646__ yyyymmL 形式的整数常量(例如, 199712L),旨在表明 wchar_t 类型的值是 ISO/IEC 10646 定义的字符的编码表示,以及 连同截至指定年份的所有修订和技术勘误,以及 月。

¶3 预定义宏的值(__FILE____LINE__ 除外)保持不变 在整个翻译单元中保持不变。

¶4 这些宏名称和定义的标识符都不应该是 #define#undef 预处理指令。任何其他预定义的宏名称 应以前导下划线开头,后跟大写字母或第二个 下划线。

¶5 实现不应预定义宏 __cplusplus,也不应定义它 在任何标准标题中。

第 6.10.8 节及其子节与 ISO/IEC 9899:2011 中的相似,但所讨论的宏集更为广泛。

【讨论】:

    【解决方案2】:

    是否为 -std=c99 提供了子选项,以便我可以通过这些子选项并避免通过 -std=c99

    不! gcc 没有提供任何此类规定。通过 -std=c99 并享受。

    【讨论】:

      【解决方案3】:

      我不这么认为,这通常是预处理器的任务

      #if __STDC_VERSION__ < 199901L
          int i;
          for(i=0;i<10;i++)
      #else
          for(int i=0;i<10;i++)
      #endif
      

      虽然在这种情况下看起来有点愚蠢。

      【讨论】:

      • 你可能需要做类似#if defined __STDC_VERSION__ &amp;&amp; __STDC_VERSION__ &lt; 199901L的事情。
      • 修改代码可能不是一个好主意,因为不同的文件中可能有许多 c99 功能。
      • @Lundin:不是真的,除非你认为你必须支持 C89 之前的编译器(是的,八十九)。在 C89 及更高版本中,处理 #if 条件时未扩展的任何符号都被视为 0。当然,C89 之前的编译器通常也不支持 defined 作为运算符,所以你会即使这样也有麻烦。因此,如果__STDC_VERSION__ 没有定义,编译器会将其视为0 并且0 小于199901L(如果它完全理解建议的#if defined ... 行)。
      • @JonathanLeffler 根据我的经验,许多 C99 之前的编译器不支持 STDC_VERSION。但是如果没有定义,预处理器将其转换为 0 是正确的,所以也许没关系。
      • 您当然可以在系统头文件中找到很多与您显示的类似的代码;我只是不相信其中一些是从“C89 之前”到“C89 之后”的过渡期的后遗症。保护并不会造成很大的伤害,但我也不确定是否会带来很大的好处。
      【解决方案4】:

      这个-std= 参数怎么样:

      ‘gnu89’ ISO C90 的 GNU 方言(包括一些 C99 特性)。这是 C 代码的默认设置。

      【讨论】:

        猜你喜欢
        • 2011-01-08
        • 2011-01-12
        • 1970-01-01
        • 1970-01-01
        • 2016-04-14
        • 2013-10-11
        • 2017-11-27
        • 1970-01-01
        • 2019-02-17
        相关资源
        最近更新 更多