C标准谈论约束,例如ISO / IEC 9899:201x定义了术语
句法或语义上的约束限制,通过这些限制来解释语言元素的说明
并在符合性一章中说
如果违反了在约束或运行时约束之外出现的“应”或“不应”要求,则该行为未定义。
在“环境”中的“诊断”小节中说
如果预处理翻译单元或翻译单元包含违反任何语法规则或约束的条件,则符合标准的实现也应至少产生一条诊断消息(以实现定义的方式标识),即使该行为也被明确指定为未定义或实现,定义。
因此,重要的是要知道C中的约束是什么,例如对于编译器编写者判断何时需要诊断,或者对于C程序员而言,何时可以期望诊断而不只是不确定的行为,这一点很重要。
现在,整个标准文档中都有标题为Constraints的部分,但是我无法找到有关术语约束在标准中确切涵盖的确切措辞。
约束是否显示在标题为约束的部分中?
从n1570 3.8的意义上讲(对程序施加了限制,要求有一个合格的实现才能在违反该规范时发出编译时诊断消息),我认为是。
在这些部分之外陈述的每个要求不是约束吗?
从3.8的意义上讲,我认为是的,但是出于更加循环的原因:该标准的结构相当正式。只要适用,似乎就会有一个明确的“约束”部分。因此,我理解从定义上讲,任何不在约束部分的东西都不是3.8的约束。
在“约束”部分之外有一些“应”子句,它们看起来完全是可在编译时执行的,请参见。下面举几个例子。它们通常在相邻的语义中部分。在一般情况下,我可能会遗漏一些微妙的细节,以至于无法进行编译时检测(以至于无法强制执行诊断),或者标准不完全一致。但是我认为编译器可以简单地翻译违规程序,正是因为要求不在“约束”部分中。
我错过的标准中是否有关于约束的全面描述?
我认为3.8就足够了。我尝试探索以下术语,并同意该定义不令人满意。
我对标准进行了更深入的研究以发现这一点。这是我的研究。
让我们从基础开始。令人惊讶的是,您引用的3.8中的“约束”的定义令人惊讶,至少在没有上下文的情况下很难理解(“语法或语义上的限制,通过这些限制来解释语言元素的说明”)。“ Restriction”和“ constraint”是同义词,因此重新措词不会增加太多;什么是“语言元素的说明”?论述是一个具有多种含义的词;让我们从Dictionary.com上获取“主要旨在传达信息的文字或语音”,并假设它们是该标准的意思。那么就意味着基本上是一个约束在这个标准就是在这个标准说的一个约束。哇,
实用地检查标准中的实际约束部分表明,它们列出了对符合标准的程序施加的编译时间限制。这是有道理的,因为在编译时只能检查编译时约束。这些附加限制是用C语法无法表达的那些限制。1个
约束部分之外的“应”的大多数用法对符合条件的实现施加了限制。示例:“具有静态存储持续时间的所有对象应在程序启动之前初始化(设置为其初始值)”,这是符合要求的实现。
但是,有一些“应”子句在“约束”部分之外对程序(而非实现)施加了限制。我会争辩说,大多数都与3.18中提到的“调用库函数时程序的运行时约束”属于同一类别。它们似乎是运行时约束,通常在编译时无法检测到(因此,诊断不是强制性的)。
这里有一些例子。
在6.5 / 7中,n1570详细讨论了备受争议的别名规则:
一个对象只能通过具有以下类型之一的左值表达式访问其存储值:
- 与对象的有效类型兼容的类型
- 与对象的有效类型兼容的类型的合格版本,[...]
在6.5.16.1中,“简单分配”:
如果从另一个对象中读取存储在一个对象中的值,而该对象与第一个对象的存储有任何重叠,则该重叠将是精确的。”
其他示例涉及指针算术(6.5.6 / 8)。
但是,还有其他的Will子句在编译时应该可以检测到它们的违背。如果它们出现在相应的“约束”部分中,我不会眨眨眼。
还有更多示例。但是正如我所说,我认为不需要执行即可诊断违规。试图越过编译器的违规程序只会暴露未定义的行为。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句