返回语句是否被视为跳转指令

Is the return statement considered a jump instruction?

本文关键字:指令 语句 是否 返回      更新时间:2023-10-16

我不是很精通c++,但是我有一个问题。我的讲师认为return是像goto一样的跳跃指令。我不同意。在我看来,return是一个控制指令,将控制转移到调用函数的地方。如果将ifwhilefor等指令视为讲师指令,也会跳过goto等指令,因为它们绕过了指令块。

我的问题是:你怎么看这个?return是一个跳转指令吗?

在这种有争议的情况下,查看c++标准并使用标准中使用的定义和术语是非常有用的。:)

根据c++标准

6.6跳转语句1跳转语句无条件转移控制权。

jump-statement:
break ;
continue ;
return expressionopt;
return braced-init-list ;
goto identifier ;

考虑到在标准中使用指令一词来表示硬件指令。它们与c++的return语句没有任何共同之处

在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',相当于return。

我认为returngoto语句之间有一个重要的区别(从比汇编语言更高级的语言的角度来看)。正如我们所知,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
}

标签AB在函数sample_fun的任何地方都是可见的,甚至在每个标签本身的声明之前,并且它不引入scopes,因此标签对变量是透明的,反之亦然。

如果在该函数的某个点跳转到同一函数的另一个点,每个"跳过"的变量将被初始化:例如,在int a = 3;中,标识符a将存在(它是可见的),如果它在相应标签的任何先前位置声明,但它的初始化器(值3)将被忽略(相应的初始化代码将不被初始化)。更有甚者,您可能跳到循环内或if语句内的某个位置,从而导致不稳定的状态,使编译器优化变得困难,等等。

虽然return语句也会导致"绕过"块指令,但它的行为/状态是"封装"的,因为函数不能访问以前作用域的局部变量,它的所有行为只取决于它的局部变量(包括参数)——好吧,存在全局变量,易失性变量和文件。

在函数内部,你只有两种可能:继续它的执行,或者退出整个函数,让每个变量一起死亡(执行相应的析构函数调用和其他清理),以及绕过函数内部的尾随指令块不会造成任何麻烦:如果在某些输入前提条件下不需要它们,为什么要执行它们?

没有面条代码,没有不稳定状态,不缺乏欠稳定性。

简而言之,return语句是一种"跳转"吗?也许,这取决于您对"跳转"的理解的首选定义,但是根据使用它们的上下文,语句goto/return绝对不同并且具有不同的属性。