[cfe-dev] Objc ivar visibility question

Jean-Daniel Dupas devlists at shadowlab.org
Mon May 10 14:29:02 PDT 2010


Le 10 mai 2010 à 20:31, Douglas Gregor a écrit :

> 
> On May 4, 2010, at 8:02 AM, Jean-Daniel Dupas wrote:
> 
>> Hello,
>> 
>> I have a question about ivar visibility in Objective-C.
>> If you try to compile the following sample code with GCC, it refuses to compile the method -bar because _parent is a private field of Foo and you try to access it from a Bar variable.
>> Actually clang behaves the same.
>> 
>> private.m:26:27: error: instance variable '_parent' is private
>>  while (parent && parent->_parent)
>>                           ^
>> private.m:27:21: error: instance variable '_parent' is private
>>    parent = parent->_parent;
>> 
>> 
>> Is there a reason why GCC and clang prevent access to a Foo private ivar from a Foo method implementation ?
>> I know that I can simply workaround this issues with a couple of casts, but by doing this I have to feeling I'm fighting against the compiler.
>> Shouldn't clang be smarter and allow that ? 
> 
> I think Clang is doing the right thing here. You're accessing a private ivar through a class of a different type than the class in which the method is being defined, so it's treated like an access to that ivar with no special privileges.  That seems like a reasonable model for access control.
> 	- Doug

The class used to access the ivar is a different class, but it is also a subclass of Foo. The _parent ivar is really a Foo ivar, even when accessed though a Bar subclass (two class cannot define ivar with the same name). That's why I find this behavior odd.

Note that this is not a blocking issue, but relaxing the check may prevent code like this:

- (Bar *)bar {
 Bar *parent = _parent;
 while (parent && ((Foo *)parent)->_parent)
   parent = ((Foo *)parent)->_parent;
 return parent;
}

Having to explicitly upcast an instance is not very usual in Obj-C.

-- Jean-Daniel


> 
>> ================================================
>> @class Bar;
>> @interface Foo {
>> @private
>>   Bar *_parent;
>> }
>> - (Foo *)foo;
>> - (Bar *)bar;
>> @end
>> 
>> @interface Bar : Foo {}
>> @end
>> 
>> @implementation Foo 
>> 
>> - (Foo *)foo {
>>  Foo *parent = _parent;
>>  while (parent && parent->_parent)
>>    parent = parent->_parent;
>>  return parent;
>> }
>> 
>> - (Bar *)bar {
>>  Bar *parent = _parent;
>>  while (parent && parent->_parent)
>>    parent = parent->_parent;
>>  return parent;
>> }
>> 
>> @end
>> ==================================================
>> 
>> 
>> -- Jean-Daniel





-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100510/3e174e8c/attachment.html>


More information about the cfe-dev mailing list