5

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.

http://clang.llvm.org/docs/AutomaticReferenceCounting.html

lockedscope
  • 965
  • 17
  • 45

2 Answers2

2

It seems that const system global variables actually do not require explicit bridging. i.e. kCFBooleanTrue(CFBoolean instance), kCFNumberNaN or kABPersonPhoneMobileLabel.

NSObject *obj = (NSObject *)kCFBooleanTrue;

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.

NSObject *obj = (NSObject *)myGlobal;

"mytest.h" File

#ifndef mytest_h
#define mytest_h

#pragma clang arc_cf_code_audited begin

typedef const struct MyStruct * MyStructPtr;

CF_EXPORT
const MyStructPtr myGlobal;

#pragma clang arc_cf_code_audited end
#endif

"mytest.c" File

#include "mytest.h"

struct MyStruct {
    int a;
};

static struct MyStruct __myglobal = { 123 };
const MyStructPtr myGlobal = &__myglobal;

--- 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.

lockedscope
  • 965
  • 17
  • 45
1

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 pragma clang arc_cf_code_audited was in effect.

Take a look at the top of CFNumber.h and you will find this:

CF_IMPLICIT_BRIDGING_ENABLED

and near the end you will find this:

CF_IMPLICIT_BRIDGING_DISABLED

These macros are defined in CFBase.h to begin and end the clang arc_cf_code_audited pragma, it it's defined.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • How exactly does 'CF_IMPLICIT_BRIDGING_ENABLED' work? Can we use them in our own API's? – Tony Mar 13 '13 at 21:54
  • Since `CF_IMPLICIT_BRIDGING_ENABLED` is simply a macro for `_Pragma("clang arc_cf_code_audited begin")`, it works by enabling a clang-specific feature. You'll have to look at the clang source code if you want to understand more. It would only make sense to use in your own API if your API were to define its own `CFType` “subclasses”. As far as I know, Apple hasn't published the API for creating `CFType` subclasses. – rob mayoff Mar 13 '13 at 22:15