简体   繁体   中英

What's the point of the local variable in Eiffel's attached-statement?

In Eiffel, Void Safety is a way to statically prevent dereferencing uninitialised ("null") objects. The way it works is that first, the object has to be declared as detachable , and then you need to check in an if-block whether the object is actually attached (ie has some value) before you can use it.

This is how I have been using it until now:

some_object: detachable TYPE

...

if attached some_object then
  some_object.method
end

Works perfectly fine: Without the attached-check, compiling fails with an "Target of the Object_call might be void" error. However, after actually reading the documentation on Void Safety, I learned that this is actually how it's supposed to look like:

some_object: detachable TYPE

...

if attached some_object as l_some_object then
  l_some_object.method
end

In this form, l_some_object is a variable local to the if-block which points to the same object as some_object but is statically guaranteed to be non-void.

However, I don't see the reason for the existence of this as-clause. As I pointed out above, apparently the original some_object is already statically guaranteed to be non-void within the if-block, so what's the point of introducing another variable?

What are the differences between some_object and l_some_object , apart from the scope?

Short answer

If some_object is a local variable, there is no point to introduce an object test local l_some_object .

Long answer

The general form of an object test is

attached {SOME_TYPE} expr as var

where {SOME_TYPE} and var are optional. When type ( {SOME_TYPE} in the example above) is not used, the object test just checks whether expr is attached or not and assigns its value to var when it is attached.

In theory something like the following could be expected to be void-safe:

if attached expr then
    expr.do_something
end

However this is not allowed in general case because expr might have side effects, so that the second time it is computed, a different value is returned, and this value might be void making the code void-unsafe:

if attached foo then -- On first call function foo returns non-void value.
    foo.do_something -- On second call function foo returns void: BOOM!
end

Another possibility is an intermediate call that changes value of the expression, for example,

if attached attr then -- Attribute attr is attached here.
    bar               -- bar sets attr to Void.
    attr.do_something -- BOOM!
end

If bar sets attribute attr to void (this can be done indirectly), the code is void-unsafe again.

Finally in a multithreading environment another thread may change the value of attr after the check and before its use inside "then" part even without any intermediate feature call:

if attached attr then -- Attribute attr is attached here.
                      -- Another thread sets attr to Void.
    attr.do_something -- BOOM!
end

To prevent these situations, the var part is used. This object test local is read-only and is not affected by an evaluation of the same expression, by any intermediate feature call or by another thread. In other words it is always attached.

Still in some situations an object tests expression is not affected by these factors:

  1. Arguments are read-only, so it is always sufficient to use the short form

     attached arg 

    and it makes no sense to introduce an object test local because it will always be equal to the argument.

  2. Local variables and Result may only become Void if they are assigned a detachable expression. If there is no such an assignment, the same

     attached local_var 

    is just fine. However as soon as the local is assigned a detachable expression, it is not considered attached anymore:

     if attached local_var then ... -- OK to use local_var as attached. local_var := detachable_expression ... -- No guarantees about local_var attachment status. end 

    If this scenario is not desired, the long form of the object test can be used

     attached local_var as attached_local_var 

    and it guarantees that attached_local_var is always attached.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM