我在C ++方面并不是很先进,但我遇到了问题。我的讲师认为return
是一个像goto
这样的跳转指令。我不同意。在我看来,return
是一个控制指令,它将控制权转移到调用函数的地方。如果被视为讲师指示,例如if
,while
,for
也会跳转goto
之类的指令,因为它们会绕过指令块。
我的问题是:你怎么看待这个? return
是跳转指令吗?
答案 0 :(得分:7)
在这些有争议的案例中,查看C ++标准并使用标准中使用的定义和术语非常有用。:)
根据C ++标准
6.6跳转语句1跳转语句无条件转移控制。
jump-statement:
break ;
continue ;
return expressionopt;
return braced-init-list ;
goto identifier ;
考虑到标准中使用的单词指令表示硬件指令。它们与C ++ return语句没有任何共同之处。
答案 1 :(得分:1)
在VS 2010中编写以下代码:
int foo ()
{
return 10;
}
在反汇编中找到以下内容:
return 10;
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 cmp dword ptr ds:[00413144h],0
0000000b je 00000012
0000000d call 65265BA7
00000012 xor edx,edx
00000014 mov dword ptr [ebp-4],edx
00000017 mov dword ptr [ebp-4],0Ah
}
0000001e mov eax,dword ptr [ebp-4]
00000021 mov esp,ebp
00000023 pop ebp
00000024 ret
最后一条指令是' ret'相当于返回。
答案 2 :(得分:0)
我认为return
和goto
语句之间存在重要差异(从高级语言而非汇编语言的角度来看)。我们知道,goto
语句需要为跳转定义label
,这些标签具有功能范围。这意味着在代码片段中,如下所示:
int sample_fun()
{
// code, possibly with local variables or gotos
A:
// code, possibly with local variables or gotos
B:
// code, possibly with local variables or gotos
}
标签A
和B
在功能sample_fun
的任何位置都可见,甚至在每个标签本身声明之前,它都不会引入scopes
,所以标签对变量是透明的,反之亦然。
如果在该函数的某个点上跳转到同一函数的另一个点,则每个“跳过”变量将被整合:例如,在int a = 3;
中,将存在标识符a
(它是可见的)如果它在相应标签的任何先前位置声明,但它的初始值设定项(值3
)将被忽略(相应的初始化代码将不会被初始化)。更重要的是,您可以跳转到循环内部或if
语句内部,导致不稳定状态,难以进行编译器优化等等。
尽管return
语句也会导致“绕过”块指令,但其行为/状态是“封装的”,因为函数无法访问先前作用域的局部变量,并且其所有行为都取决于只有它的局部变量(包括参数)--Ok,存在全局变量,volatile变量和文件。
在一个函数中,你只有两种可能:继续执行,或者退出整个函数,让每个变量都死掉(执行相应的析构函数调用和其他清理),并绕过尾随函数内部的指令块不会造成任何麻烦:如果你在某些输入前置条件下不需要它们,为什么要执行它们呢?
没有意大利面条代码,没有不稳定状态,不缺乏可靠性。
简而言之,return
语句是一种“跳跃”吗?也许,这取决于您对“跳跃”所理解的内容的首选定义,但根据使用的上下文,语句goto
/ return
明确地不同且具有不同的属性。