C 标准谈论约束,例如。 G。 ISO/IEC 9899:201x 定义了该术语
constraint
restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted
并在第 章一致性 中说
If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined.
在章节 环境 , 小节 诊断 据说
A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined.
因此,了解 C 中的约束是很重要的,例如对于编译器编写者判断何时需要诊断,或者对于 C 程序员何时需要诊断而不仅仅是未定义的行为。
现在,整个标准文档都有标题为 Constraints 的部分,但我找不到关于标准中术语约束到底涵盖什么内容的明确措辞。
最佳答案
Are the constraints everything that appears in the sections titled Constraints?
在 n1570 3.8 的意义上(对程序施加的限制,该程序需要符合要求的实现才能在违反时发出编译时诊断消息),我认为是的。
Is every requirement that is stated outside of those sections not a constraint?
在 3.8 的意义上,我认为是的,但出于更循环的原因:标准的结构相当正式。只要适用,似乎就有一个明确的约束部分。因此,我理解根据定义,任何不在约束部分中的内容都不是 3.8 意义上的约束。
在 Constraints 部分之外有一些“shall”子句,它们看起来完全可以在编译时强制执行,参见。下面举几个例子。它们通常位于相邻的语义部分。我可能遗漏了在一般情况下阻止编译时检测的微妙之处(因此不能强制进行诊断),或者标准可能不完全一致。但我认为编译器可以简单地翻译一个违规的程序,正是因为这些要求不在约束部分。
Is there a comprehensive description of constraint in the standard that I missed?
我认为 3.8 就是你所得到的。我尝试探索下面的术语并同意该定义不令人满意。
我更深入地研究了标准以找出答案。这是我的研究。
术语约束
让我们从基础开始。您引用的 3.8 中“约束”的定义令人惊讶地难以理解,至少在没有上下文的情况下(“要解释语言元素的说明的句法或语义限制”)。 “限制”和“约束”是同义词,所以改写不会增加太多; “语言元素的阐述”是什么意思??博览会是一个有多种含义的词;让我们以来自 Dictionary.com 的“主要用于传达信息的写作或演讲”为例,让我们假设他们的意思是标准。那么它基本上意味着本标准中的约束是本标准中所说的约束。哇,我没想到。
根据 3.8 的约束
务实地检查标准中的实际约束部分显示它们列出 强加于符合程序的编译时间限制。 这是有道理的,因为在编译时只能检查编译时约束。
这些额外的限制是不能用 C 语法表达的。 1
约束部分之外的约束
约束部分之外“应”的大多数用法对符合要求的实现施加限制。 示例:“所有具有静态存储持续时间的对象都应被初始化(设置为它们的
初始值)在程序启动之前”,符合实现的工作。
但是,有一些“应”子句对约束部分之外的程序(而不是实现)施加了限制。我认为大多数与 3.18 中提到的“调用库函数时程序上的运行时约束 [...]”属于同一类别。它们似乎是在编译时通常无法检测到的运行时约束(因此诊断不是强制性的)。
这里有一些例子。
在 6.5/7 n1570 中详细介绍了备受争议的别名规则:
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
- a type compatible with the effective type of the object
- a qualified version of a type compatible with the effective type of the object, [...]
在 6.5.16.1,“简单赋值”中:
If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the overlap shall be exact[..]."
其他示例涉及指针算术 (6.5.6/8)。
可以在约束部分中的 SHALL 子句
但是还有其他应该在编译时检测到违规的shall子句;如果它们出现在相应的约束部分,我不会眨眼。
表达式应仅将算术类型转换为整数类型”(在“语义”下);如果无法检测常量和强制转换的类型,您在编译时可以检测到什么?
还有几个例子。但正如我所说,我认为不需要实现来诊断违规行为。设法绕过编译器的违规程序只会暴露未定义的行为。
1 例如,我知道语法不处理类型——它只有通用的“表达式”。因此,每个运算符都有一个约束部分,详细说明其参数的允许类型。移位运算符示例:“每个操作数都应具有整数类型。”试图移动浮点数位的程序违反了此约束,实现必须发出诊断信息。
关于c - 标准 C 中的约束是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33409241/