标准C中的约束是什么?

C标准谈论约束 ,例如ISO / IEC 9899:201x定义术语

约束
限制,无论是句法还是语义,通过它来解释语言元素的阐述

并在章节一致性中

如果违反约束或运行时约束之外的”shall”或”shall not”要求,则行为未定义。

据说环境 ,分段诊断这一章

如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合的实现应生成至少一个诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现 – 定义。

因此,重要的是要知道C中的约束是什么,例如,编译器编写者判断何时需要诊断,或者C编程人员可以预期诊断而不仅仅是未定义的行为。
现在,标准文档中有一些标题为Constraints的部分 ,但是我找不到关于标准中术语约束究竟是什么的明确措辞。

  • 约束是否出现在标题为约束的部分中?
  • 在这些部分之外陈述的每项要求都不是约束条件吗?
  • 我错过了标准中的约束的全面描述吗?

约束是否出现在标题为约束的部分中?

在n1570 3.8的意义上(对程序施加的限制,要求在违反时要求符合标准的实现发出编译时诊断消息),我认为是的。

在这些部分之外陈述的每项要求都不是约束条件吗?

在3.8的意义上,我认为是的,但是出于更循环的原因:标准的结构是相当正式的。 只要适用,似乎有一个明确的约束部分。 因此,据我所知, 根据定义,任何不在约束条款中的东西都不是3.8意义上的约束。
Constraints部分之外有一些“shall”子句,它们看起来完全可编译时可执行,参见 下面举几个例子。 它们通常位于相邻的Semantics部分中。 我可能会遗漏在一般情况下阻止编译时检测的细微差别(因此不能强制诊断),或者标准可能不完全一致。 但我认为编译器可以简单地翻译违规程序,正是因为要求不在Constraints部分。

我错过了标准中的约束的全面描述吗?

我认为3.8就是你得到的。 我尝试探索下面的术语并同意该定义不令人满意。


我更深入地研究了标准以找到它。 这是我的研究。

术语约束

让我们从基础开始。 你引用的3.8中“约束”的定义令人惊讶地难以理解,至少没有语境(“限制,无论是句法还是语义,通过它来解释语言元素的阐述”)。 “限制”和“约束”是同义词,因此重写不会增加太多; 什么是“语言元素的阐述”? 博览会是一个含有多种含义的词; 让我们从Dictionary.com采取“主要用于传达信息的写作或演讲” ,让我们假设它们意味着标准。 那么它基本上意味着该标准中的约束是本标准中所述内容的约束。 哇,我不会猜到的。

约束 3.8

务实地只检查标准中的实际约束部分表明它们列出了对符合程序施加的编译时限制。 这是有道理的,因为在编译时只能检查编译时约束。 这些附加限制是那些无法用C语法表达的限制。 1

约束部分之外的约束

约束部分之外的“shall”的大多数使用都对符合要求的实现施加了限制。 示例: “具有静态存储持续时间的所有对象应在程序启动之前初始化(设置为其初始值)”,这是一个符合要求的实现的工作。

但是,有一些“必须”条款对Constraints部分之外的程序 (不是实现)施加限制。 我认为大多数都属于与3.18中提到的“调用库函数时程序的运行时约束[…]相同的类别”。 它们似乎是运行时限制,通常在编译时无法检测到(因此诊断不能强制执行)。

这里有一些例子。

在6.5 / 7 n1570详细介绍了备受争议的别名规则:

对象的存储值只能由具有以下类型之一的左值表达式访问:

  • 与对象的有效类型兼容的类型
  • 与对象的有效类型兼容的类型的限定版本,[…]

在6.5.16.1中,“简单分配”:

如果从另一个以第一个对象的存储方式重叠的对象读取存储在对象中的值,那么重叠应该是精确的[..]。“

其他示例涉及指针算法(6.5.6 / 8)。

应该约束条款中的条款

但是还有其他条款,在编译时可以检测到违规; 如果它们出现在相应的约束部分中,我就不会眨眼。

  • 6.6 / 6, “整数常量表达式中的转换运算符只能将算术类型转换为整数类型” (在“语义”下); 如果你不能检测常量和强制类型的类型,你可以在编译时检测到什么?
  • 6.7 / 7, “如果声明对象的标识符没有链接,则对象的类型应在其声明者的末尾完成” (在“语义”下)。 对我来说,似乎是一个基本的编译器任务,用于检测代码中某个类型是否完整。 但当然,我从未编写过C编译器。

还有一些例子。 但正如我所说,我认为诊断违规行为不需要实施。 设法偷偷通过编译器的违规程序只会暴露未定义的行为。


1例如,我理解语法不处理类型 – 它只有通用的“表达式”。 因此,每个运算符都有一个Constraints部分,详细说明了其参数的允许类型。 移位运算符的示例: “每个操作数都应具有整数类型。” 试图移动浮点位的程序违反了这个约束,并且实现必须发出诊断。

C委员会在对缺陷报告#033的回复中解决了这个问题。 该缺陷报告中的问题是:

是否需要符合标准的实施方法来诊断标准中所有违反“应该”和“不应该”的陈述,即使这些陈述发生在标记为约束的部分之外?

该缺陷报告的作者提出了几种可能的解释标准语言的替代方法。 他列出的第二个选择(部分):

语法规则是标准的“ 语法”部分中列出的那些项。 约束是标准的约束部分中列出的那些项。

委员会的部分回应是:

建议的解释#2是正确的。

我相信这完全涵盖了您的问题,但只是更直接地陈述您的问题的答案:

  • 约束是否出现在标题为约束的部分中?
  • 在这些部分之外陈述的每项要求都不是约束条件吗?

“约束”是在明确标记为“约束”的部分中陈述的要求。 在该部分之外陈述的任何要求不是约束。

  • 我错过了标准中的约束的全面描述吗?

至少据我所知,标准本身并不包含关于什么是约束或什么不是约束的更具体的陈述,但链接的缺陷报告确实如此。

约束是否出现在标题为约束的部分中?

看起来它们大多数(有些情况不是,fx:它表示“增量相当于在一个约束部分中加1”)。

在这些部分之外陈述的每项要求都不是约束条件吗?

我没有在这些部分之外看到“约束”。

我错过了标准中的约束的全面描述吗?

可能不是,如果有一个权威的,它将在标准中并且可能是“约束”部分(并明确提到这些都是“约束”)。

我的解释是,第3章应该被解释为使得对定义的术语的每次使用都具有该部分中定义的含义。 特别是在任何地方使用术语“约束”时,应根据您的第一个引用来理解。

你的第二句话也不例外。 在术语“约束”的定义中注意到,不要求约束明确地称为约束。 这意味着您必须通过检查它是否是这样的限制来确定它是否是“约束”。

然而,似乎有很多“应该”和“不应该”的例子可以被视为这种限制而没有明确地称之为这样的限制。 这将使所有出现的“应该”和“不应该”强制执行或禁止实现的某些行为 – 如果这些行为未得到满足,那么行为可能是不确定的(因为你使用的实现不是’符合标准)。

看起来所有符合“约束”定义的似乎都出现在“约束”部分下,而“约束”部分中的所有内容似乎都是“约束”。

约束是否出现在标题为约束的部分中?

是。 标准中提到的每个语法和语义限制都是约束。

例如,对常量表达式的约束(C11-6.6 / 3):

常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未评估的子表达式中。 115)

因此,常量表达式

 3 = 5; 10++; 

显示约束违规。

请注意,在这种情况下, 必须违反要求和约束

在这些部分之外陈述的每项要求都不是约束条件吗?

对于标准符合C,是的。 A要求整数常量表达式(C11-6.6 / 6):

整数常量表达式117) 具有整数类型[…]

例如,非可变长度数组的大小需要整数常量表达式。 因此,

 int arr[5+1.5]; 

违反了要求。 表达式5+1.5类型不是整数类型。 这要求不受限制。

应该指出的是要求也可能是一种约束。

在我的需求工程工作中,“约束”和“需求”这两个词的范围不同。 同样,对于标准来说,明确地定义它们也很重要。 我在标准中搜索了“约束”这个词,似乎我可以得出以下结论:

约束是对标准部分描述的行为的输入(前置条件)或输出(后置条件)的限制。 对于输入,它意味着输入必须遵守约束(例如, argc应为正)。 对于输出,它意味着它必须满足标准的任何后续单位的约束,以具有明确定义的输入(其前置条件)。

要求是标准部分行为规范的一部分。 “应该”是对所需要的积极描述; “不应”通常是一种限制,但不是一种限制 – 它可能会参与限制其输出。

约束和要求可以被视为“外部接口”(约束)和“系统行为/处理”(要求)。

通常表示要求(没有“应”的短语因此不是要求)。 然后,在约束中使用的“应该”用于定义输入或输出(例如, argc应为正)或指定有关validation约束的行为(例如“……应给出诊断消息”)。

严格地说,用于指定validation输入约束的行为的“必须”不应列在约束部分中(不应在接口规范中列出),而应列在处理部分(行为部分)中。

请注意,输出约束无法validation,因为输出应符合规范; 如果它们处于输入约束中,则只有下一个uit可以检查这些约束。

这可能是个人观点,但它似乎符合标准中这些词语的用法。

约束

限制,无论是句法还是语义,通过它来解释语言元素的阐述

这意味着c standart以任何方式设置的程序逻辑或语法的每个显式限制都是约束。 这包括句法约束(例如,块必须以;终止)和语义约束(例如,在初始化之前不得使用变量),基本上是语法(符号方式)或语义上的所有内容(使用正确的符号方式) )不允许或定义为不允许(未定义的行为)。

在这些部分之外陈述的每项要求都不是约束条件吗?

我确实认为C语言编程的所有明确要求都属于句法或语义约束。

我错过了标准中的约束的全面描述吗?

不是我的知识。