Objc ivar visibility question

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 ?

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

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

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?