`
tomqyp
  • 浏览: 25693 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

谨慎使用scope定义局部变量

阅读更多

今天,一个小错误浪费了大半天的时间。

 

我在一个函数中使用scope定义了一个局部临时变量,后来又无意中将其它对象赋值给这个临时变量,并进行了一些操作,当走出函数时,gc自动释放了临时变量最后所指向的对象,一但有程序再对这个对象进行操作时,就有可能引发一个av错误。

 

因为,离开时只会释放scope变量最后所指向的对象,而其它大部份对象却不受影响,所以错误可能会随机出现,让问题比较隐蔽。同时,发现av错误时,通常注意力都会集中在对象是否正创建和释放,而忽略了scope的影响,所以使得找出原因更加困难。

分享到:
评论
11 楼 tomqyp 2008-11-30  
这个果然很适合scope  学习
10 楼 redsea 2008-11-30  
[quote tomqyp]
我用 scope 变量来做 autolock/unlock, 这个很适合 scope 的发挥.

可以详细介绍下么?



这个应该没有什么啊, 就是 RAII 的普通应用而已.

就想我的一个通信程序, 有不少函数调用的时候, 必须要 reactor 加锁, 让人记住是很烦的, 所以我就给这些函数加一个 LockToken 参数, 就是类似下面的.

scope class LockToken
{
    private Mutex mutex_;

    this(IBaseSelector selector)
    {
        mutex_ = selector.getMutex();
        mutex_.lock();
    }

    ~this()
    {
        mutex_.unlock();
    }

    private void lock()  { mutex_.lock(); }
    private void unlock(){ mutex_.unlock(); }
}



9 楼 redsea 2008-11-30  
另外, 在实践中发现, 手工内存管理/scope auto 变量 和 gc 一起用, 相当危险.

现在我还是寄希望于 d 语言的 gc 性能以后越做越好, 除了真正 performance critial 的内层循环之外, 别的地方都不要自己进行手工内存管理了.
8 楼 tomqyp 2008-11-25  
[quote redsea]
我用 scope 变量来做 autolock/unlock, 这个很适合 scope 的发挥.


可以详细介绍下么?
7 楼 redsea 2008-11-24  
我用 scope 变量来做 autolock/unlock, 这个很适合 scope 的发挥.

其他的东西, 如果内存或者什么开销不大, 就不 scope 了.
6 楼 oldrev 2008-11-22  
scope 是 D 最 awesome 的东东了,绝不应该取消,不过还是建议WB提供一个类似 C# using(){} 的语法,或者作为替代,用大括号包住 scope 的作用域,并在第一行就声明 scope 对象:


void foo()
{
  {
    scope auto x = new X();
    ....
  }
}
5 楼 dogstar 2008-11-20  
个人觉得这种情况就不应该编译过去.这样犯错的机会就小多了.让人记住这些可能出问题的坑,不靠谱.
4 楼 tomqyp 2008-11-20  
嘿嘿 实现 foreach时,采用的是 scope 局部变量就应该格外小心。
3 楼 Colorful 2008-11-20  
还有个 scope 修饰的类,呵呵。

俺正在衡量 scope 类和继承 IDisposable 接口的类,到底哪种设计好。

目前 D-Phoenix 中的迭代器实现 foreach 上,采用的是 scope 局部变量的设计。

PS: scope 的用法还真是多样,还有 scope(exit), scope(failure)。
2 楼 tomqyp 2008-11-20  
Colorful 写道

scope 局部变量已经足已说明它的适用范围。

它实际上就是函数体内的临时变量,不要把函数体范围外的变量赋值给 scope 局部变量。


当然,可以让人牢记scope的适用范围,但这至少有悖D的设计思想。也许编译时给个警告可以让人更容易避免这类底级错误。

其实写这个并还是为了抱怨,只是想记录一些自己的心得,当然也希望对其它遇到类似问题的人有所帮助。
1 楼 Colorful 2008-11-20  
scope 局部变量已经足已说明它的适用范围。

它实际上就是函数体内的临时变量,不要把函数体范围外的变量赋值给 scope 局部变量。

相关推荐

Global site tag (gtag.js) - Google Analytics