Search code examples
objective-cccocoaglobal-variablesstatic-variables

How different static variable declarations in Objective-C?


Please look into this header:

// Test.h
@interface Test : NSObject @end

extern id A;               // (0)
//extern static id B;      // (1) Uncomment to get a compiling error
extern id C;               // (2)
//extern static id D;      // (3) Uncomment to get a compiling error

And into this implementation:

// Test.m
#import "Test.h"

id A = @"A";               // (4)
static id B = @"B";        // (5)

@implementation Test

id C = @"C";               // (6)
static id D = @"D";        // (7)

@end

// Still Test.m

@interface Test2 : NSObject @end
@implementation Test2 : NSObject

+ (void)initialize {
    NSLog(@"%@ %@", A, B); // (8)
    NSLog(@"%@ %@", C, D); // (9)
}

@end

I have the following questions:

  1. Is there any fundamental difference between declarations (4) and (5) or (6) and (7)?
  2. Is there any difference between the “external” declaration (4) and the enclosed into implementation scope (6)?
  3. Why (6) and (7) declared within implementation scope can be accessed in another implementation scope (9)?
  4. Why (2) declared in header can access (6) declared within implementation scope?
  5. Why (1) and (3) generate errors Cannot combine with previous 'extern' declaration specifier, but (0) and (2) are compiled with no errors?

Solution

    1. Yes, static used in this context limits the variable to the scope of the file.

      If you have (4) and declare id A = @"A" in another file in the project, even without the extern declaration in the header, then you'll get a compiler error.

      In the case of (5) if you declare static id B = @"B" in another files then it will work fine.

    2. No, these are C variable declarations and don't follow Objective-C scoping rules.

    3. Since Objective-C is a superset of C, (6) and (7) are simply global variables declared like they would be in C.

    4. (2) doesn't really reference (6), it simply declares to other files which #import it "Trust me, there's a variable called C declared in another file", which is later resolved later when the compiled object files are linked.

    5. As mentioned previously static limits scope of variables to the current file, so it conflicts with extern which says that the variable is declared in another file.