Beyond Distributed Objects, one of these annotations appears to be used by ARC. I came across the following in clang's description of passing to an out parameter by writeback:
If the parameter is not an Objective-C method parameter marked out
, then *p
is read, and the result is written into the temporary with primitive semantics.
This has to do with methods like - (BOOL)executeWithError:(out NSError **)error
.
Ignoring the out
keyword, ARC has a well-defined behavior of treating by-reference object passing as __autoreleasing
, so ARC treats the error
parameter as having a type of NSError * __autoreleasing *
. If you use an otherwise qualified variable, ARC will add a temporary autoreleasing variable pass into the function (for coherence):
Original code
NSError *error;
[obj executeWithError:&error];
Pseudotransformed code
NSError * __strong error;
NSError * __autoreleasing temp;
temp = error;
[obj executeWithError:&temp];
error = temp;
With the above code, the line temp = error
would be unnecessary if we could somehow know that temp
will never be read. This is where the out
annotation comes into play. Per the quoted description if out
is missing the compiler must add the line temp = error
but if it does contain out
it can exclude the line and make the code just a little bit smaller/faster. With out
the transformed code becomes:
NSError * __strong error;
NSError * __autoreleasing temp;
[obj executeWithError:&temp];
error = temp;
Of course, if you're that worried about binary size and speed, you should just code the following:
NSError * __autoreleasing error;
[obj executeWithError:&error];
It is entirely possible that these annotations are used other places throughout the compiler and runtime, and may be used in more places in the future. Personally, I like using out
as a hint to other developers that I'm not going to read the value.