[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