tikhop
tikhop

Reputation: 2087

Difference between external variable of some sort and static variable

What the difference between external variable of some sort and static variable?

//ClassA.m
NSString *var1;
static NSString *var2;

@implementation ClassA

...

Upvotes: 2

Views: 1743

Answers (3)

justin
justin

Reputation: 104698

extern

An extern constant/variable is one which one definition may be accessed (or referenced) across multiple object files. It's a global, exported C symbol. Use this if you want access to the constant/global variable from multiple translation units (or compiled files) or if you want to use it in multiple binaries (e.g. you want to use it from your app, and the definition is in a dynamic library). You will typically declare this in the header for others to use.

static

The static emits a copy for each translation. Each file that is compiled which also sees (e.g. is #included) the static will emit a copy of that static. You should avoid this. This will result in a bloated binary that has very confusing execution. You should favor the static if the value is local to a file, and should be private to that file.

For these reasons, you should favor static in your .c, .m, .cpp, and .mm files, and extern in your headers.

Finally, that NSString pointer should be const by default:

// declaration - file.h
extern NSString * const var1;

// definition - file.m
NSString * const var1 = @"var1";

or

static NSString * const var2 = @"var2";

If you still want more, here's a related answer I wrote, and here's another.

Upvotes: 3

CRD
CRD

Reputation: 53000

Global variables and static

Declaring a variable outside of any method (and in Objective-C either within, or outside, @implementation/@end makes the lifetime of the variable global, that is the variable will exist during the whole time period the application is executing.

A global variable with no qualification, or only with const and/or volatile qualifiers, is visible from anywhere. So for example:

NSString *MyApplicationName;

declares a global variable MyApplicationName which can be accessed from any place in the application.

The visibility of a global variable (but not its lifetime) can be restricted to just the file (more accurately "compilation unit" allowing for one file including others) containing the declaration by qualifying it with static. So for example:

static NSString *MyClassName;

declares a global variable MyClassName which is only visible from the current compilation unit.

Using static qualified global declarations within @implementation/@end is the closest thing Objective-C offers to other languages' "class variables".

You should not place global variable declarations, static qualified or not, in header files as that would result in multiple distinct declarations - an error will result if there is no static qualifier, and multiple distinct variables with different visibility scopes if there is one.

The extern qualifier

The extern qualifier does something rather different.

The original meaning (a small relaxation is now allowed, see below) is to just define the type and name of a global variable which is declared elsewhere. That is you are telling the compiler "there is a global variable of some type and name I'd like to use which will be supplied by another compilation unit". For example:

extern NSString *MyApplicationName;

states that some compilation unit contains the declaration (which must not be static qualified):

NSString *MyApplicationName;

The extern qualified declaration does not itself cause the allocation of any storage for the global variable.

You do place extern qualified declarations in header files, this is how a compilation unit advertises the global variables it wishes to export. You can also place them in code files to reference globals variables declared elsewhere. Within a code file you can place an extern qualified declaration either outside of any method/function - in which case the name/type is available for to whole compilation unit - or within a method/function - in which case the visibility of the name/type is limited to just that method/function.

The small relaxation

Originally you had to have one non-extern qualifier declaration to satisfy any extern qualified ones. However this was later changed, if on linking the various compilation units together none of them declare a global variable referenced by some extern qualified declaration then the linker (usually?) just generates the variable itself and adds it to the resultant binary rather than producing a "missing global" error. Best programming practice is not to rely on this relaxation - always have a none-extern qualified declaration for every global variable.

Upvotes: 2

dtuckernet
dtuckernet

Reputation: 7895

I could give an explanation, but it wouldn't be as good as this one:

http://blog.ablepear.com/2010/01/objective-c-tuesdays-static-variables.html

Upvotes: 1

Related Questions