为什么 for 语句中 init-statement 末尾的分号是强制性的?
Why is the semicolon at the end of the init-statement within the for statement mandatory?
这是 C++17 标准定义 for 语句的方式:
for ( init-statement conditionₒₚₜ ; expressionₒₚₜ ) statement
我也看过 https://en.cppreference.com/w/cpp/language/for:
attr(optional) for ( init-statement condition(optional) ; iteration_expression(optional) ) statement
因此,我只能理解在使用for循环时init-statement不是可选的。换句话说,必须在 header 中初始化一些变量才能使用这种控制流机制。好吧,情况似乎并非如此,因为当我键入诸如
之类的代码时
for (; a != b; ++a)
假设我已经定义了这些变量,它运行得很好。我不仅没有在header中声明变量,还引用了之前在循环外定义的其他变量。如果我要提供一个 init-statement,它的 object 只能在 for 循环内使用,但似乎我可以使用在其他地方声明的变量就好了。
得出这个结论后,我认为我不需要第一部分:尝试删除分号以使其更具可读性(好吧,只是为了它)。它现在不会编译。编译器说它期望 ;
,计算 a != b
就好像它不在 for 循环中一样:"C4552: '!=': 未使用表达式的结果" 最后得出结论:"C2143: syntax error: missing ';'在“)”之前.
您不需要 init-statement,但您确实需要分号。为什么我引用的这些资源最初没有明确说明这一点,还是以某种我视而不见的方式暗示了这一点?
分号是必需的,因为 init-statement
包括分号。
引自N3337 6.5迭代语句:
for (for-init-statement condition_{opt}; expression_{opt}) statement
for-init-statement:
expression-statement
simple-declaration
6.2表达式语句:
expression-statement:
expression_{opt} ;
7 个声明:
simple-declaration:
decl-specifier-seq_{opt} init-declaratior-list_{opt} ;
attribute-specifier-seq decl-specifier-seq_{opt} init-declarator-list ;
如果您查找 init-statement 并跟踪 the possibilities,您会发现它们都需要一个尾随分号。
iteration-statement:
for
(
for-init-statement conditionₒₚₜ ;
expressionₒₚₜ )
statement
for-init-statement:
expression-statement
simple-declaration
expression-statement:
expressionₒₚₜ ;
simple-declaration:
attribute-specifier-seqₒₚₜ decl-specifier-seqₒₚₜ init-declarator-listₒₚₜ ;
A for-init-statement 是 expression-statement 或 simple-declaration. expression-statement 有一个可选的表达式,但有一个强制分号。同样,简单声明的组件都是可选的,除了最后的分号。
Why didn't these resources I cited initially made this clear, or is it implied in some way I am blind to?
语言标准
您引用的第一个资源是 C++17 标准。语言标准的编写是精确和一致的。通常(如您的情况)细节被推迟到其他部分,因此无论使用频率如何,每个定义只出现一次。休闲编码员阅读的方便性不是优先考虑的问题。标准的第一句规定了文件的范围。
This document specifies requirements for implementations of the C++ programming language.
注意这些要求是针对谁的。它们用于 实现 ,更常见但不准确地称为“编译器”。该标准不是为那些编写 C++ 程序的人编写的;它是为那些编写 C++ 编译器(以及实现的其他部分)的人编写的。这就是为什么此资源不关心从程序员的角度阐明要点。
cppreference.com
编码人员通常需要进行大量解释才能从标准中提取他们需要的内容。这就是为什么有教语言的书籍和资源,例如您的第二个引文,cppreference.com。将标准的既定目的与 that of cppreference.com 进行对比:
Our goal is to provide programmers with a complete online reference for the C and C++ languages and standard libraries, i.e. a more convenient version of the C and C++ standards.
该网站的目标受众是程序员,而不是实施者。因此,标准的严苛精度已被更多的解释冲淡。它试图在严格的正确性和可读性之间取得平衡,对需要检查语言某些方面的细节的编码人员有一点同理心。
在这个特殊情况下,我认为他们做了合理的工作。我想你只是忽略了解释?
您复制了“正式语法”行。紧接着是“非正式语法”行,用 declaration-or-expression(optional) ;
替换了令人困惑的 init-statement
,清楚地表明分号是必需的,但分号之前不需要出现任何内容。
语法行之后是相关定义的列表。 init-statement
的定义表明它“可能是空语句 ;
”。此外,定义以
结尾
Note that any init-statement
must end with a semicolon ;
, which is why it is often described informally as an expression or a declaration followed by a semicolon.
注意,定义直接在相关页面。这是网站在呈现方式上与标准不同的一种方式。由于网站不是最终权威,因此如果不一致则影响较小。这使它可以自由地重复自己,并冒定义不相同的风险。恰当的例子:init-statement
的定义在 if
statement article 中重复(其中 init-statement
是可选的)。
也许重要的是阅读这些定义,而不是假设您已经知道它们的含义?
这是 C++17 标准定义 for 语句的方式:
for ( init-statement conditionₒₚₜ ; expressionₒₚₜ ) statement
我也看过 https://en.cppreference.com/w/cpp/language/for:
attr(optional) for ( init-statement condition(optional) ; iteration_expression(optional) ) statement
因此,我只能理解在使用for循环时init-statement不是可选的。换句话说,必须在 header 中初始化一些变量才能使用这种控制流机制。好吧,情况似乎并非如此,因为当我键入诸如
之类的代码时for (; a != b; ++a)
假设我已经定义了这些变量,它运行得很好。我不仅没有在header中声明变量,还引用了之前在循环外定义的其他变量。如果我要提供一个 init-statement,它的 object 只能在 for 循环内使用,但似乎我可以使用在其他地方声明的变量就好了。
得出这个结论后,我认为我不需要第一部分:尝试删除分号以使其更具可读性(好吧,只是为了它)。它现在不会编译。编译器说它期望 ;
,计算 a != b
就好像它不在 for 循环中一样:"C4552: '!=': 未使用表达式的结果" 最后得出结论:"C2143: syntax error: missing ';'在“)”之前.
您不需要 init-statement,但您确实需要分号。为什么我引用的这些资源最初没有明确说明这一点,还是以某种我视而不见的方式暗示了这一点?
分号是必需的,因为 init-statement
包括分号。
引自N3337 6.5迭代语句:
for (for-init-statement condition_{opt}; expression_{opt}) statement for-init-statement: expression-statement simple-declaration
6.2表达式语句:
expression-statement: expression_{opt} ;
7 个声明:
simple-declaration: decl-specifier-seq_{opt} init-declaratior-list_{opt} ; attribute-specifier-seq decl-specifier-seq_{opt} init-declarator-list ;
如果您查找 init-statement 并跟踪 the possibilities,您会发现它们都需要一个尾随分号。
iteration-statement:
for
(
for-init-statement conditionₒₚₜ;
expressionₒₚₜ)
statementfor-init-statement:
expression-statement
simple-declarationexpression-statement:
expressionₒₚₜ;
simple-declaration:
attribute-specifier-seqₒₚₜ decl-specifier-seqₒₚₜ init-declarator-listₒₚₜ;
A for-init-statement 是 expression-statement 或 simple-declaration. expression-statement 有一个可选的表达式,但有一个强制分号。同样,简单声明的组件都是可选的,除了最后的分号。
Why didn't these resources I cited initially made this clear, or is it implied in some way I am blind to?
语言标准
您引用的第一个资源是 C++17 标准。语言标准的编写是精确和一致的。通常(如您的情况)细节被推迟到其他部分,因此无论使用频率如何,每个定义只出现一次。休闲编码员阅读的方便性不是优先考虑的问题。标准的第一句规定了文件的范围。
This document specifies requirements for implementations of the C++ programming language.
注意这些要求是针对谁的。它们用于 实现 ,更常见但不准确地称为“编译器”。该标准不是为那些编写 C++ 程序的人编写的;它是为那些编写 C++ 编译器(以及实现的其他部分)的人编写的。这就是为什么此资源不关心从程序员的角度阐明要点。
cppreference.com
编码人员通常需要进行大量解释才能从标准中提取他们需要的内容。这就是为什么有教语言的书籍和资源,例如您的第二个引文,cppreference.com。将标准的既定目的与 that of cppreference.com 进行对比:
Our goal is to provide programmers with a complete online reference for the C and C++ languages and standard libraries, i.e. a more convenient version of the C and C++ standards.
该网站的目标受众是程序员,而不是实施者。因此,标准的严苛精度已被更多的解释冲淡。它试图在严格的正确性和可读性之间取得平衡,对需要检查语言某些方面的细节的编码人员有一点同理心。
在这个特殊情况下,我认为他们做了合理的工作。我想你只是忽略了解释?
您复制了“正式语法”行。紧接着是“非正式语法”行,用 declaration-or-expression(optional) ;
替换了令人困惑的 init-statement
,清楚地表明分号是必需的,但分号之前不需要出现任何内容。
语法行之后是相关定义的列表。 init-statement
的定义表明它“可能是空语句 ;
”。此外,定义以
Note that any
init-statement
must end with a semicolon;
, which is why it is often described informally as an expression or a declaration followed by a semicolon.
注意,定义直接在相关页面。这是网站在呈现方式上与标准不同的一种方式。由于网站不是最终权威,因此如果不一致则影响较小。这使它可以自由地重复自己,并冒定义不相同的风险。恰当的例子:init-statement
的定义在 if
statement article 中重复(其中 init-statement
是可选的)。
也许重要的是阅读这些定义,而不是假设您已经知道它们的含义?