Objc ivar visibility question

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Objc ivar visibility question

Jean-Daniel Dupas-2
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 ? 

================================================
@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





_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Objc ivar visibility question

Douglas Gregor

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

================================================
@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




_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Objc ivar visibility question

Jean-Daniel Dupas-2

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





_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Objc ivar visibility question

Jacob Carlborg
On 5/10/10 23:29, Jean-Daniel Dupas wrote:

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

As far as I know this is how most object oriented language behave
(perhpas not the part about the ivar). It seems you want to use
protected, which also is the default for ivars in Objective-C, can't you
use that?

> 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
>
>
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev