Is special meaning of C statements inside of Objective-C class sections intended?

Hello, folks. Not sure if this is the right place for asking such a question, but it seems i’ve run out of options. Neither Apple’s “The Objective-C Programming Language” nor Programming with Objective-C book mention this explicitly. So it’s apparently some implementation details that come into play here. Consider the following code:

@implementation TDWClass

- (void)method {
    bar(); // the function is accessible here despite not being declared in the code before
}

void bar(void) {
    NSLog(@"Test");
}

@end

If bar was declared after @end, the method method would fail to find it, so it means there is some special name lookup inside of @implementation section not only for Objective-C methods but also for plain C functions (the same is applicable for global/static variables declared inside of the section). Also such C-functions have access to private ivars:

@implementation TDWClass {
@private
    int _var;
}

- (void)foo {
    bar(self);
}

void bar(TDWClass *self) {
    self->_var += 2; // a private instance variable accessed
}

@end

Some sources also say that static variables inside of @implementantion section had special meaning (unlike C the variables are private to the enclosing class, not the compilation unit), however I could not reproduce this on my end.

I wonder if such a behaviour is intended, part of Objective-C language or it’s some side-effect which should not be expected to be consistent in future releases?

Thanks in advance.

Hey folks. Sorry for pinging, but it seems the question didn’t quite get enough attention. If it’s not the appropriate place for asking such a question, i would appreciate any clue where else i can ask to get better chance for answers? Thank you

Not needing a forward declaration of bar there is news to me. As for the private/protected ivar accesses inside a C function inside an @implementation, that’s something that Apple’s Objective-C code relies on, and it’s also “documented” in SemaExprMember.cpp.

1 Like

Thank you for the insight. Does it mean, that while automatic-forward-declaration might be subject to change in future releases, access to the private context of the Objective-C class is rather part of the design?

If I’m reading ParseObjc.cpp correctly, the “automatic forward declaration” behavior is intentional, too. When an @implementation is parsed, the method and function declarations are parsed first, with their body tokens stashed away (see StashAwayMethodOrFunctionBodyTokens()) until @end is reached.

Interestingly, this suggests you can’t reference later-declared C functions in the declaration of earlier methods, and indeed it errors if you try.

@implementation Foo
- (int (*)[baz /* this is an error */])bar {
    (void)baz; /* this is OK */
}
const int baz = 9;
@end

Finally, do also remember that Hyrum’s Law applies here. :slight_smile:

1 Like