C11的最新变化

36

C1x已经成为ISO/IEC 9899:2011,也就是C11。

有没有人知道标准从2011年4月草案n1570到现在有哪些变化(如果有的话)?

预计:这里有来自伦敦(2011年3月)的委员会会议记录(应该包括在n1570中)此处, 和来自华盛顿特区的记录(2011年10月)此处; 我想列出DC会议中接受的更改清单应该可以涵盖所有内容。


8
根据Larry Jones在comp.std.c上的评论,N1569(没有变更标记的N1570)与其相比没有显著变化。唯一仍未解决的问题是__STDC_VERSION__的值,但我猜它最自然的值将是201112L - Jens Gustedt
谢谢您提供的信息,@JensGustedt。顺便说一句,我链接到n1570是因为该链接是公开可访问的;n1569也可以下载,但不能直接下载。 - J. C. Salomon
@JohanBezem,他们甚至忘了这个?所以我们可以发布第一个缺陷报告 :) 幸运的是,它只使用整数,因此通过对201100L进行测试应该是安全的。 - Jens Gustedt
@JensGustedt 我刚刚删除了自己的评论,因为你已经描述了情况,没有什么可补充的。我认为这对于“首次发布”来说是正常的,因为ISO过程非常复杂,你永远不知道它是否会在圣诞节前完成,但你必须提供最终的准备就绪的文档。我想我们最好像你建议的那样使用 <201100L>= 201101L。但我想这不被认为是一个缺陷。 - Johan Bezem
我也正在详细阅读n1570,并研究它与最终标准之间的差异。我主要集中于语言的最终类型层次结构 - Krzysztof Abramowicz
3个回答

16
我今天刚刚了解到,在N1570和最终的C11标准(ISO/IEC 9899:2011 (E))之间有一个(有点)重要的变化。
在N1570中,6.3.2p3说:
除非它是sizeof运算符、_Alignof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串字面量,类型为“type数组”的表达式将被转换为类型为“指向数组对象的初始元素的type指针”的表达式,并且不是左值。
包含_Alignof是一个错误,因为unary-expression语法允许这种情况。
_Alignof ( type-name )

但不是

_Alignof unary-expression

发布的C11标准纠正了这个错误并恢复了C99的措辞:

除了作为sizeof运算符或一元&运算符的操作数,或用于初始化数组的字符串文字之外,具有“类型为数组类型”的表达式会转化为一个具有“指向数组对象的初始元素”的类型指针类型的表达式,并且不是lvalue。

更多信息:在最近发布的ISO C委员会成员Larry Jones有关N1570和发布标准之间差异的帖子中,他写道:

有很多这样的差异,但大多数只是一些次要的编辑调整、对样板文本的更改以及调整顺序以使高层人员满意。最大的变化是从许多它不应该添加的地方移除了_Alignof(基于错误的观念,即它像sizeof一样接受类型或表达式,而实际上它只接受类型):6.3.2.1p2、p3、p4、fn. 65;和6.7.1 fn. 121。

消息ID:<rfg33a-u0q.ln1@jones.homeip.net>groups.google.com上看到的帖子。

5

以下是来自 Jens Gustedt 在评论中的回答:

根据 Larry Jones 在 comp.std.c 上的评论,从 N1569 到 N1570 (没有变化标记的 N1570)之间没有重大变化。唯一未解决的问题是 __STDC_VERSION__ 的值,但我猜最自然的值将是 201112L


5
2011年的官方标准错误定义了__STDC_VERSION__和可选的__STDC_LIB_EXT1__。第一个技术勘误将两者都定义为201112L。请注意,本翻译不包含解释或额外内容。 - Keith Thompson

1
ISO已经批准并发布ISO/IEC 9899:2011标准作为C编程语言的新C11(C1x)标准。与先前的标准(C99)相比,根据C11维基百科文章所述,主要变化如下:
标准包括对 C99 语言和库规范的若干更改,例如:
  • 对齐规范(_Alignas 说明符、_Alignof 运算符、aligned_alloc 函数、<stdalign.h> 头文件)
  • _Noreturn 函数说明符
  • 使用 _Generic 关键字进行类型泛化表达式。例如,以下宏 cbrt(x) 根据 x 的类型翻译为 cbrtl(x)cbrt(x)cbrtf(x)

        #define cbrt(X) _Generic((X), long double: cbrtl, \
                                      default: cbrt, \
                                      float: cbrtf)(X)
    
  • 多线程支持(_Thread_local 存储类说明符、<threads.h> 头文件包含线程创建/管理函数、互斥锁、条件变量和线程本地存储功能,以及无法中断对象访问的 _Atomic 类型限定符和 <stdatomic.h>)。
  • 基于 C Unicode 技术报告 ISO/IEC TR 19769:2004 的改进的 Unicode 支持(char16_tchar32_t 类型用于存储 UTF-16/UTF-32 编码的数据,包括在 <uchar.h> 中的转换函数和相应的 uU 字符串字面前缀,以及用于 UTF-8 编码字面量的 u8 前缀)。
  • 删除了在上一个 C 语言标准修订版 ISO/IEC 9899:1999/Cor.3:2007(E) 中已过时的 gets 函数,采用新的安全替代品 gets_s
  • 边界检查接口(附录 K)。
  • 可分析性特征(附录 L)。
  • 更多用于查询浮点类型特性的宏,涉及次法浮点数和类型能够存储的十进制位数。
  • 匿名结构和联合体,在联合体和结构嵌套时非常有用,例如在 struct T { int tag; union { float x; int n; }; }; 中。
  • 静态断言,它们在翻译期间进行评估,比 #if#error 使用时更晚一些,当翻译器理解类型时。
  • fopen 的独占创建和打开模式("…x" 后缀)。这类似于 POSIX 中的 O_CREAT|O_EXCL,通常用于锁文件。
  • 作为第三种终止程序的方式的 quick_exit 函数,旨在在无法通过 exit 终止时进行至少最小化的去初始化。
  • 用于构造复数值的宏(部分原因是 real + imaginary*I 如果 imaginary 是无穷大或 NaN 可能不会产生预期的值)。

从ISO网站上,您可以购买完整的已发布标准。以下是从ISO网站上摘录的摘要:

ISO/IEC 9899:2011 规定了 C 语言程序的形式和解释。它规定了:
- C 程序的表示形式; - C 语言的语法和限制; - 解释 C 程序的语义规则; - 要由 C 程序处理的输入数据的表示形式; - C 程序产生的输出数据的表示形式; - 符合 C 实现所施加的限制和限制。
ISO/IEC 9899:2011 不规定:
- 将 C 程序转换为数据处理系统使用的机制; - 调用 C 程序以供数据处理系统使用的机制; - 将输入数据转换为 C 程序使用的机制; - 在由 C 程序生成后将输出数据转换的机制; - 程序及其数据的大小或复杂性,将超出任何特定数据处理系统或特定处理器的容量; - 支持符合实现的数据处理系统的所有最小要求。
ISO/IEC 9899:2011 旨在促进 C 程序在各种数据处理系统之间的可移植性。它适用于实现者和程序员。

2
这甚至没有试图回答所问的问题,这与C11和C99之间的差异无关。 - Mark Amery
我同意@MarkAmery的观点。这个问题是关于N1570和最终发布的C11之间的区别。 - AJM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接