ARC and refcount semantics attributes

Hi list, I just discovered these attributes on a page about the static analyzer:

__attribute((ns_return_retained))
__attribute((ns_consumed))

I am curious whether the current implementation of ARC respects these attributes, or if there are plans to support them. It seems important that it would for cases where autorelease pools are not practical.

Thanks!
George

Hi list, I just discovered these attributes on a page about the static analyzer:

__attribute((ns_return_retained))
__attribute((ns_consumed))

I am curious whether the current implementation of ARC respects these attributes, or if there are plans to support them.

Yep, they are. More information about ARC is here:
http://clang.llvm.org/docs/AutomaticReferenceCounting.html

It seems important that it would for cases where autorelease pools are not practical.

What do you mean?

-Chris

Hi list, I just discovered these attributes on a page about the static analyzer:

__attribute((ns_return_retained))
__attribute((ns_consumed))

Incorrect spelling aside, this is easy for you to check:

$ cat arc.m
id unretained(void);

__attribute((ns_returns_retained))
id retained(void)
{
  return unretained();
}

void consume(__attribute((ns_consumed)) id y){}
$ clang -fobjc-nonfragile-abi -fobjc-arc -S -emit-llvm arc.m

The resulting file is arc.s. Snipping some irrelevant details, we're left with:

define i8* @retained() {
  %1 = call i8* @unretained()
  %2 = call i8* @objc_retainAutoreleasedReturnValue(i8* %1) nounwind
  ret i8* %2
}

As you can see, the function with the ns_returns_retained attribute that returns the result of a call to a function without this attribute (which, implicitly, returns an autoreleased object) retains the value. objc_retainAutoreleasedReturnValue() is a special case of -retain that is faster if the object has just been autoreleased with objc_autoreleaseReturnValue().

Now what about the other function:

define void @consume(i8* %y) nounwind {
  %1 = alloca i8*, align 4
  store i8* %y, i8** %1, align 4
  %2 = load i8** %1
  call void @objc_release(i8* %2) nounwind, !clang.imprecise_release !0
  ret void
}

As you can see, this function implicitly releases the argument by calling objc_release() on it.

I am curious whether the current implementation of ARC respects these attributes, or if there are plans to support them. It seems important that it would for cases where autorelease pools are not practical.

I'm not sure what you mean by 'where autorelease pools are not practical'. ARC requires autorelease pools to work...

David

-- Sent from my Apple II

Incorrect spelling aside, this is easy for you to check:

My mistake - typing code questions on a phone is error-prone!

I'm not sure what you mean by 'where autorelease pools are not practical'. ARC requires autorelease pools to work...

In fact I had missed a documentation detail. I am passing objects between threads using performSelector:onThread:withObject:waitUntilDone: and did not see that the argument is retained until after the target thread performs the selector. I was concerned that the caller's run loop pool would drain before the target thread got the message. Sorry for the noise, and thanks for the detailed explanation - it was very informative!