标准C中的约束是什么?

Arm*_*ali 26 c standards language-lawyer

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

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

并在章节一致性中

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

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

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

因此,重要的是要知道C中的约束是什么,例如编译器编写者判断何时需要诊断,或者对于C编程人员来说,当诊断而不仅仅是未定义的行为时.
现在,标准文档中有一些标题为Constraints的部分,但我找不到关于术语约束在标准中涵盖的内容的确切措辞.

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

Pet*_*ica 9

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

在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部分,详细说明了其参数的允许类型.移位运算符的示例:"每个操作数都应具有整数类型." 试图移动浮点数的程序违反了这个约束,并且实现必须发出诊断.


Jer*_*fin 7

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

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

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

语法规则是标准的" 语法"部分中列出的那些项.约束条件是标准的" 约束"部分中列出的项目.

委员会的部分回应是:

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

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

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

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

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

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