我想对C的常量表达式有一个准确的理解。所以,我阅读了C99的相关规定。“6.6 常量表达式”一章的第一条描述了常量表达式的语法,但我看不懂。
C99的“6.6常量表达式”一章第一条规定:
常量表达式:
条件表达式
为什么 C99 使用条件表达式来解释常量表达式?毫无疑问,表达式 2 + 3 是一个常量表达式。是条件表达式吗?
我想对C的常量表达式有一个准确的理解。所以,我阅读了C99的相关规定。“6.6 常量表达式”一章的第一条描述了常量表达式的语法,但我看不懂。
C99的“6.6常量表达式”一章第一条规定:
常量表达式:
条件表达式
为什么 C99 使用条件表达式来解释常量表达式?毫无疑问,表达式 2 + 3 是一个常量表达式。是条件表达式吗?
要理解 §6.6 常量表达式,您需要了解语法的工作方式,并且需要阅读 §6.5 表达式。
在 §6.5 表达式中,第 6.5.15 节条件表达式说:
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
这是标准指定优先级等的方式。这个想法是将赋值运算符和逗号表达式排除在“常量表达式”之外,但允许其余大部分内容,受第 6.6 节中定义的约束(其中,除其他外, 明确排除赋值和逗号运算符,可能是因为规则中的通用表达式确实包含它们)。
符号“常量表达式:条件表达式”只是常量表达式语法的规范。语法描述了可能是常量表达式的字符串。除了满足语法之外,常量表达式还必须满足 6.6 节中列出的约束。
C 标准使用“常量表达式:条件表达式”这一事实可能令人困惑。但是,如果标准使用“constant-expression: expression”,那将是完全相同的,如下所示。也就是说,任何表达式都是常量表达式,只要它不仅遵循表达式的语法,而且遵循第 6.6 节中列出的约束条件。
条件表达式的一个示例是3 < 4 ? 5 : 6
。这个表达式也是一个常量表达式,因为它满足第 6.6 节中的约束。另一方面,x < 4 ? 5 : 6
它也是一个条件表达式,但不是一个常量表达式(假设x
是一个对象的名称,而不是一个被常量替换的宏,等等)。
第 6.6 节告诉您,如果条件表达式满足约束条件,则它可能是常量表达式。第 6.5.15 条显示条件表达式可以是 alogical-OR-expression
或 a logical-OR-expression ? expression : conditional-expression
。继续通过链工作,alogical-OR-expression
可能是 alogical-AND-expression
或可能是使用逻辑 OR 运算符构建的表达式,||
。尽管每个级别的名称都类似于foo-expression
,但每个级别实际上要么是之前出现的表达式类型,要么是用 构建的表达式foo
。foo-expression-or-prior-type-of-expression
将它们命名而不是仅命名会很麻烦foo-expression
。
因此,语法从主要元素开始,它们是标识符、常量、字符串字面量,以及我稍后将讨论的一个特殊事物,并且语法将这些主要元素构建成更复杂的表达式,增加了使用 C 允许的每个运算符的可能性. 以这种方式对语法进行分层定义了运算符的优先级,因为在可能的情况下,必须在后面的表达式之前解析较早的表达式。
主要的特别之处是一个带括号的表达式,( expression )
. expression
令牌是定义链的末端,在 6.5.17 中定义。这将语法循环回去;任何表达式都可以放在括号中,这使它成为一个新primary
的,然后可以对其应用运算符。
第 6.6 条可以声明 aconstant-expression
是 a expression
,它与说它是 a 具有相同的效果conditional-expression
。这是因为 6.6 中的约束禁止赋值运算符和逗号运算符。因此,如果我们考虑 anexpression
可能是什么,第 6.5.17 条说它可以是 anassignment-expression
或expression , assignment-expression
。但是禁止逗号运算符的约束禁止后者。因此,expression
常量表达式中的 a 必须是 a assignment-expression
。同样, anassignment-expression
必须是 aconditional-expression
而不是unary-expression assignment-operator assignment-expression
。
首先,C 标准没有解释任何东西。它说明了 C 语言是如何定义的,但没有说明原因。
语法部分是用一种特殊语言(EBNF的一种变体)编写的,用于描述编译器应如何解释 C 源代码。规范
constant-expression:
conditional-expression
本质上意味着常量表达式使用与 a 相同的语法conditional-expression
。在关于条件运算符 (6.5.15) 的部分中,您会发现一个类似的语法部分定义了 aconditional-expression
是如何构建的。
如果跟踪所有语法规则,您会发现 aconstant-expression
可以使用除赋值运算符 ( =, *=, /=, +=, -=, <<=, >>= &=, ^=, |=
) 和逗号运算符( ) 之外的任何运算符,
(除非它们被括在括号中)。