If i understood correctly we could classify void * as a "C retainable pointer type". So, assigning it to an Objective-C object will be implicitly bridged. However, compiler raises error that explicit bridging is required.
const void * somePtr = (void *)0x12345678;
- (void)someMethod:(id)sender
{
NSObject *obj = (NSObject *)somePtr;
}
Also, i checked the null pointer constant and it compiles without explicit bridging.
NSObject *obj = (void *)0;
I am using XCode 4.5(Clang 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)).
Question: I know it's a little bit weird to assign some arbitrary/irrelevant pointer to NSObject but i want to make sure if am correctly understanding the rules. I am little bit suspicious about the "C retainable pointer type". description; especially about the intention of (possibly qualified) and (possibly qualifier). What pointer types could we classify as "C retainable pointer type"?
Also, does it actually mean a global variable from system by the "system global variable" statement?
3.3.2. Conversion to retainable object pointer type of expressions with known semantics [beginning Apple 4.0, LLVM 3.1]
An expression is known retain-agnostic if it is:
- an Objective-C string literal,
- a load from a const system global variable of C retainable pointer type,
- or a null pointer constant.
If the cast operand is known unretained or known retain-agnostic, the conversion is treated as a __bridge cast.
7.8. C retainable pointer types
A type is a C retainable pointer type if it is a pointer to (possibly qualified) void or a pointer to a (possibly qualifier) struct or class type.
It seems that const system global variables actually do not require explicit bridging. i.e. kCFBooleanTrue(CFBoolean instance), kCFNumberNaN or kABPersonPhoneMobileLabel.
Note that CFBoolean is not toll free bridged but it could be still implicitly bridged by compiler. I define global constants but could not get them compiled with implicit bridging. So, i wonder how could compiler determine if a variable comes from system or not? (Or may be it is checking if type comes from CoreFoundation.framework which is not a neat solution...)
--- EDIT ---
Referring to rob mayoff's answer, i tried implicit bridging but it still did not work. May be there is a compiler flag to determine the file as a Core Foundation file.
"mytest.h" File
"mytest.c" File
--- EDIT ---
I also modified the CFNumber.h header file in CoreFoundation.framework and removed CF_IMPLICIT_BRIDGING_ENABLED/CF_IMPLICIT_BRIDGING_DISABLED, then clean/build the project and yet it did not disable implicit bridging for those constants.
Although it's not stated in the document you linked, I believe the “system” part of “a
const
system global variable” means the variable was defined while the pragmaclang arc_cf_code_audited
was in effect.Take a look at the top of
CFNumber.h
and you will find this:and near the end you will find this:
These macros are defined in
CFBase.h
to begin and end theclang arc_cf_code_audited
pragma, it it's defined.