我有一些简单的 C++ 代码:
#include <iostream>
int main(){
{
int a = 10;
tag:
std::cout << a << std::endl;
}
goto tag;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在我知道使用它不是一个好主意goto,如果我跳转goto到其他范围,我会收到编译错误。我已经尝试过了,它自然会给我一个明显的编译错误。但我的问题是是否有任何方法可以使其进入无限循环
我问这个问题是因为这个问题
我注意到问题中的代码是C++代码而不是C代码。然而,这个问题是带有 C 和 C++ 双重标签的,这很令人厌烦,因为 C 和 C++ 的规则不同。
\n\n问题中的 C++ 代码不应编译。用 C 编写的类似代码应该可以编译,但最终结果是无限循环。
\n\n在 ISO/IEC 14882:2011(C++11 标准;我没有 2014 年标准的正式副本可供报告)中,它说:
\n\n\n\n\n6.6.4 goto 语句 [stmt.goto]
\n\n\xc2\xb61 该
\n\ngoto语句无条件地将控制转移到由标识符标记的语句。标识符应是位于当前函数中的标签(6.1)。6.7 声明语句[stmt.dcl]
\n\n\xc2\xb61 声明语句将一个或多个新标识符引入块中;它的形式为声明-语句:\n 块声明\n 如果声明引入的标识符先前已在外部块中声明,则外部声明对该块的其余部分隐藏,之后恢复其效力。
\n\n\xc2\xb62 具有自动存储期限(3.7.3)的变量在每次执行其声明语句时都会被初始化。在块中声明的具有自动存储持续时间的变量在退出块时被销毁(6.6)。
\n\n\xc2\xb63 可以转移到块中,但不能以绕过初始化声明的方式。从具有自动存储持续时间的变量不在范围内的点跳转到其在范围内的点的程序是格式错误的,除非该变量具有标量类型、具有简单默认构造函数和简单析构函数的类类型,这些类型之一的 cv 限定版本,或上述类型之一的数组,并且在声明时不使用初始值设定项 (8.5)。
\n\n87) 从 switch 语句的条件到 case 标签的转移在这方面被认为是跳转。
\n
尽管普通int是标量类型,但跳转会绕过初始化,因此是不允许的。
在 ISO/IEC 9899:2011(C11 标准)中,它说:
\n\n\n\n\n6.8.6.1
\n\ngoto声明约束
\n\n
\n \xc2\xb61 语句中的标识符goto应命名位于封闭函数中某处的标签。语句goto不得从具有可变修改类型的标识符的范围之外跳转到该标识符的范围之内。语义
\n
\n \xc2\xb62 goto 语句会导致无条件跳转到封闭函数中以命名标签为前缀的语句。
请注意,违反约束需要进行诊断。违反语义部分的规则不需要诊断。
\n\n附件一(常见警告)是一份信息性附件,而非规范性附件,其中写道:
\n\n\n\n\n\xe2\x80\x94 具有自动存储持续时间的对象初始化的块被跳转到(6.2.4)。
\n
和
\n\n\n\n\n6.2.4 对象的存储时长
\n\n\xc2\xb65 其标识符声明时没有链接且没有存储类说明符的对象
\n\nstatic具有自动存储持续时间,某些复合文字也是如此。尝试从与对象关联的线程以外的线程间接访问具有自动存储持续时间的对象的结果是实现定义的。\xc2\xb66 对于这样一个不具有可变长度数组类型的对象,其生命周期从进入与其关联的块开始一直延伸到该块的执行以任何方式结束。(输入封闭的块或调用函数会暂停但不会结束当前块的执行。)如果递归地输入块,则每次都会创建对象的新实例。对象的初始值是不确定的。如果为对象指定了初始化,则每次在执行块时到达声明或复合文字时都会执行初始化;否则,每次到达声明时该值都会变得不确定。
\n\n\xc2\xb67 对于这样一个具有可变长度数组类型的对象,它的生命周期从对象的声明开始延伸,直到程序的执行离开声明的范围。35)如果递归进入作用域,则每次都会创建一个新的对象实例。对象的初始值是不确定的。
\n\n35) 离开包含声明的最内层块,或者跳转到该块中的某个点或声明之前的嵌入块,会离开声明的范围。
\n
请注意,问题中的代码中没有可变修改类型(没有 VLA 或可变长度数组)。标准 C++ 不支持 VLA 的概念(尽管 GNU C++ 编译器允许将它们作为扩展)。
\n\n代码 (goto1.c):
#include <stdio.h>\nint main(void)\n{\n {\n int a = 10;\ntag:\n printf("%d\\n", a);\n }\n goto tag;\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n示例编译:
\n\n$ gcc -std=c11 -O3 -g -Wall -Wextra -Werror goto1.c -o goto1\n$\nRun Code Online (Sandbox Code Playgroud)\n\n这些是相当严格的警告选项,GCC 不会发出任何窥视 \xe2\x80\x94 的声音,根据 C 标准的规定,这是允许的行为。
\n| 归档时间: |
|
| 查看次数: |
280 次 |
| 最近记录: |