`
tomqyp
  • 浏览: 26161 次
  • 性别: 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 局部变量。

相关推荐

    Python语言基础:局部变量和全局变量.pptx

    在Python编程语言中,了解和正确使用局部变量与全局变量是非常重要的基础知识。它们的主要区别在于作用域和可访问性。 **局部变量(Local Variables)**: 局部变量是在函数内部定义的,只在该函数的代码块中有效。...

    JavaScript程序设计课件:变量的作用范围.pptx

    局部变量是在函数内部定义的变量。它们仅在其所在的函数内部可见,外部无法访问。当函数执行完毕,局部变量通常会被销毁,除非该函数内部有闭包(Closure)的情况,使得局部变量的生命周期得以延长。局部作用域有助...

    深入理解变量作用域

    因此,即使全局有一个名为`scope`的变量,但在`checkScope`函数内部,仍然会输出局部变量`scope`的值。 #### 四、闭包 1. **闭包的概念** - 闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包最常见的...

    编译_程序中定义的的标识符是否正确

    - 使用`static`关键字修饰局部变量,可以使其在函数每次调用时保持其值,而不是像普通局部变量那样每次调用都会初始化。 ```cpp void func() { static int count = 0; count++; // 每次调用func(),count都会...

    c代码-8.变量的有效范围(作用域)

    局部变量是在函数内部或者代码块(如`{}`)中定义的变量。它们只在其定义的函数或代码块内可见,并且在函数调用结束后或代码块执行完毕后被销毁。局部变量只在当前执行环境中占用内存,因此不会与其他函数或代码块中...

    Python语言基础:作用域.pptx

    内部函数可以访问外部函数的非局部变量,但在外部函数中不能直接访问内部函数的局部变量。 - **全局作用域(Global, G)**:这是整个脚本的最外层,全局变量在整个脚本的任何地方都可以被访问,除非被局部作用域...

    Python 中的 global 标识对变量作用域的影响

    4. **仅使用未声明的变量**:如果在函数内部直接使用未声明的变量,Python会假设这是要引用全局变量,只要该函数中没有同名的局部变量定义。 通过以下示例可以更清晰地理解这些规则: ```python dumplings = '...

    参数传递与作用域PPT学习教案.pptx

    1. **局部作用域(Local Scope)**:在函数内部定义的变量具有局部作用域,只能在其定义的函数或代码块内部访问。一旦函数执行完毕,这些变量就会被销毁,例如`GetMax()`函数中的`result`变量。 2. **全局作用域...

    Python作用域用法实例详解

    Python中的作用域是控制...`global`和`nonlocal`关键字允许我们在需要的时候跨越作用域边界,但应谨慎使用,因为过度依赖全局变量可能导致代码难以理解和调试。理解这些概念对于编写高效、可靠的Python代码至关重要。

    php代码-参数作用域

    2. **局部作用域(Local Scope)**:在函数内部定义的变量具有局部作用域,它们只在该函数内部可见。一旦函数执行完毕,这些变量就会被销毁。 3. **静态作用域(Static Scope)**:使用`static`关键字定义的变量在...

    Python命名空间及作用域原理实例解析

    Python中的命名空间和作用域是理解程序执行逻辑和变量访问规则的关键概念。命名空间(Namespace)可以被看作是一个从名字到对象的映射,它决定了变量名...在编程实践中,优先考虑使用局部变量和参数传递来管理状态。

    《C++ Primer》学习笔记(24)类

    - **成员函数的作用域**:`clear` 函数中的 `Window_mgr` 指出了这是一个类的成员函数,所有在函数内部定义的标识符(如局部变量、参数等)都位于该函数的作用域内。 - **返回类型与类的关系**:如果一个成员函数的...

    c++ 类基本概念易错点

    - 在成员函数内部,`this`可以用来区分局部变量和成员变量。 8. **作用域解析运算符(scope resolution operator)** - `::`运算符用于访问全局或嵌套作用域中的标识符,如`ClassName::member`。 - 在类成员函数...

    深入浅析JS Function()构造函数

    而Function()构造函数创建的函数,其代码的编译总是发生在顶层,也就是说它只能够访问全局作用域内的变量,而无法访问到其被创建时所在作用域的局部变量。 这可以通过一个例子来进一步说明: ```javascript var ...

    学习Angular中作用域需要注意的坑

    在上述例子中,`$scope.a`被定义为基本类型(数字),因此,当`InnerCtrl`尝试修改`a`时,它实际上是在创建一个新的局部变量,而不是修改父作用域中的`a`。这就是为什么内部按钮点击后,只有内部的`a`会改变。 2. *...

    深入浅出理解JavaScript闭包的功能与用法

    在这个作用域内定义的变量都是局部变量,它们只在函数执行期间存在。函数执行完毕后,按照一般的理解,这些变量的生命周期就结束了,它们所占用的内存应该被垃圾回收机制回收。然而,如果在函数内部定义了一个嵌套...

Global site tag (gtag.js) - Google Analytics