Search code examples
objective-cextern

What does extern mean in an obj-c header


what does this code mean?

// myheader.h
extern const NSUInteger Something;

@interface MyObject : NSObject
...
@end

What does extern mean here, and how can/will it be used? is it part of the object? is it global in the project? Does it matter where (in which header) is it defined? Is that a good practice?


Solution

  • This is plain C.

    What does extern mean here, and how can/will it be used?

    extern const NSUInteger Something;
    

    It means:

    • There is a var with the name Something.

    • It has the type NSUInteger.

    • It cannot be changed (const)

    • Do not create that var, but link to a creation somewhere else in a file contained in the executable (extern).

    Let's have an example:

    Exporter.h

    extern const NSUInteger Something;
    

    Exporter.m (Or Exporter.c, since it is plain C.)

    #import "Exporter.h"
    const NSUInteger Something = 5;        // This is the definition for the declaration above.
    

    After defining that var in Exporter.m and extern declaring it in Exporter.h everyone that imports the Header can use it:

    Importer.h or Importer.m (Or Importer.c, since it is plain C.)

    #import "Exporter.h" (Or #include, since it is plain C.)
    
    // Now the compiler knows that 
    // there is a global readonly var called Something, 
    // its type is int, and
    // it is readonly.
    

    Every importer will share one var. Without the extern keyword, there would be different vars.

    Is it part of the object?

    No. To be precise: An ivar is declared, if it is inside {}that belongs to an @interface … or to an @implementation …. Whether this is done in a header or in an .m file is without any meaning.

    Is it global in the project

    It is global in your executable. (You call that "project" what is not precise, but okay.)

    Does it matter where (in which header) is it defined?

    No. That never matters in C. (The compiler sees the text after resolving imports and includes. It has no idea from where it came.) But in one translation unit (".m") you have to have a definition as shown above in Exporter.m.

    Is that a good practice?

    The problem with extern var declaration is that everyone importing Exporter.h can read and – that's important – change that var without any notification to other parts of your software dealing with Exporter.h (and Something). So it is nearly impossible to control the data flow.

    In nowadays extern global vars are only used for const vars, as in your Q. That vars cannot be changed. So there is no problem and it is commonly accepted practice.