Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can local and register variables be declared extern?

Tags:

c

extern

I have been wondering whether an extern can be declared locally and a register variable. If it can be what would be the restrictions imposed?

like image 829
Av03 Avatar asked Jan 15 '13 10:01

Av03


People also ask

Can we declare extern as local variable?

An external variable may also be declared inside a function. In this case the extern keyword must be used, otherwise the compiler will consider it a definition of a local (automatic) variable, which has a different scope, lifetime and initial value.

Can extern variables be initialized?

You can initialize any object with the extern storage class specifier at global scope in C or at namespace scope in C++. The initializer for an extern object must either: Appear as part of the definition and the initial value must be described by a constant expression; or.

Can you declare a variable is both static and extern?

3.1. Static variables in C have the following two properties: They cannot be accessed from any other file. Thus, prefixes “ extern ” and “ static ” cannot be used in the same declaration. They maintain their value throughout the execution of the program independently of the scope in which they are defined.

Are global variables extern?

External variables are also known as global variables. These variables are defined outside the function. These variables are available globally throughout the function execution.


1 Answers

Local variables can be declared extern in some cases

Let's read the C99 N1256 standard draft.

The standard calls "local variables" as having "block scope".

6.7.1/5 "Storage-class specifiers" says:

The declaration of an identifier for a function that has block scope shall have no explicit storage-class specifier other than extern.

Then for what it means to add extern to a local variable, 6.2.2/4 "Linkages of identifiers" says:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

Lets break down those cases.

no prior declaration

void f() {
    extern int i;
}

is the same as:

extern int i;
void f() {}

except that the declaration is only visible inside f.

This is because i has no prior declaration visible. So i has external linkage (the same linkage as global variables).

prior declaration specifies no linkage

int i;
void f() {
    extern int i;
}

is the same as:

void f() {
    extern int i;
}

because the prior declaration int i specifies no linkage because paragraph 6 says:

The following identifiers have no linkage: an identifier declared to be anything other than an object or a function; an identifier declared to be a function parameter; a block scope identifier for an object declared without the storage-class specifier extern.

prior declaration specifies internal or external linkage

extern int i;
void f() {
    extern int i;
}

is the same as:

extern int i;
void f() {}

and:

static int i;
void f() {
    extern int i;
}

is the same as:

static int i;
void f() {}

because in both cases we have a previous visible external and internal (static) linkage declarations respectively.

Initialize local extern

Invalid C:

void f() {
    extern int i = 0;
}

because the block scope declaration has an initialization.

Valid C:

extern int i = 0;
void f() {}

but arguably bad style because equivalent to the shorter:

int i = 0;
void f() {}

because 6.7.8 Initialization says:

If the declaration of an identifier has block scope, and the identifier has external or internal linkage, the declaration shall have no initializer for the identifier.