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:
Cannot combine with previous 'extern' declaration specifier
, but (0) and (2) are compiled with no errors?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.
No, these are C variable declarations and don't follow Objective-C scoping rules.
Since Objective-C is a superset of C, (6) and (7) are simply global variables declared like they would be in C.
(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.
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.