调用函数时传入参数加上括号结果不同,求原因!

niewb 2011-09-14 02:32:38
工作中出现一个BUG,查了好久才发现问题所在,举个简单的例子,如下:

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim i As Integer
Dim j As Integer

i = 90
j = i

sss(i)
sss((j))
Me.Text = i & ";" & j
End Sub

Private Sub sss(ByRef i As Integer)
i = i * 2
End Sub

以上代码,同是调用sss,传入的参数i和j,值相同,不同的是j加了括号。
调用结束后i=180,j=90
苦思不得其解,求原因
...全文
267 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
风骑士之怒 2011-09-15
  • 打赏
  • 举报
回复
分析下IL

1.不加()

Sub Main()
Dim i As Integer
Dim j As Integer

i = 90
j = i

sss(i)
sss(j)
End Sub

Private Sub sss(ByRef i As Integer)
i = i * 2
End Sub


IL代码:

.locals init ([0] int32 i,
[1] int32 j)
IL_0000: nop
IL_0001: ldc.i4.s 90
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: stloc.1
IL_0006: ldloca.s i
IL_0008: call void ConsoleApplication2.Module1::sss(int32&)
IL_000d: nop
IL_000e: ldloca.s j
IL_0010: call void ConsoleApplication2.Module1::sss(int32&)


这里只是将局部变量i和j的引用地址推送到了计算堆栈上,并没什么区别,下面再看看加了括号的版本

2. 加()
上述C#代码的 sss(j) 改成 sss((j))

如下IL代码:

.locals init ([0] int32 i,
[1] int32 j,
[2] int32 VB$t_i4$S0)
IL_0000: nop
IL_0001: ldc.i4.s 90
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: stloc.1
IL_0006: ldloca.s i
IL_0008: call void ConsoleApplication2.Module1::sss(int32&)
IL_000d: nop
IL_000e: ldloc.1
IL_000f: stloc.2
IL_0010: ldloca.s VB$t_i4$S0
IL_0012: call void ConsoleApplication2.Module1::sss(int32&)


发现多了一个名为VB$t_i4$S0的局部变量,和第一个例子的IL代码的区别主要是下面三句代码:
IL_000e: ldloc.1 //将索引为1的局部变量(即j)加载到计算堆栈上
IL_000f: stloc.2 //从计算堆栈的顶部弹出当前值并将其存储到索引2的局部变量(即VB$t_i4$S0

IL_0010: ldloca.s VB$t_i4$S0 //将位于特定索引处的局部变量的地址加载到计算堆栈上

发现这里已经没j什么事情了,j还是原来的i的值,即90
niewb 2011-09-15
  • 打赏
  • 举报
回复
楼上的正解,特别是分析问题的方法相当正确!
我以前没关心过.net的中间代码,也就从没想过从这个方向入手分析。
看来我有必要学习一下IL了。
CCJustLearn 2011-09-14
  • 打赏
  • 举报
回复
按引用调用是不是必须传一个左值?编译器认为加了括号的是右值,默认改成byval了吧。
btxdlibin 2011-09-14
  • 打赏
  • 举报
回复
()本身是一个运算符吧,运算过后应该是指向了一个新的临时地址.
(j)这时你传的不是变量j的地址,而是一个临时地址了。

个人观点,仅供参考!

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧