The use of extern in libraries, and also for const global variables

Preamble

A friend got me thinking about extern the other day, as they were having an issue with chapter 7, Beginning C for Arduino by Jack Purdum.

Meat and Two veg

Libraries should use extern in the header for the declaration of global variables, and the sketch which uses that library should provide the actual definition of the global.

For example, assuming that a library requires a global variable indicating which pin is used for a particular LED, then the library’s header should declare the global variable

extern int myLEDPin;

the sketch itself should then define the variable

int myLEDPin = 13;

From Re: When / how to use extern modifier

If you want to use that library in other places, or share it with other people, they would need to edit the .h file to put their SSID value in. Not a good idea. The library (or libraries) should all use extern, and expect the sketch to define/declare SSID.

Something about const global variables

Another point for const global variables is that that will always require extern, even for the definition.

From this answer to When to use extern in C++

In C++, a const variable has internal linkage by default (not like C).

So this scenario will lead to linking error:

Source 1 :

const int global = 255; //wrong way to make a definition of global const variable in C++

Source 2 :

extern const int global; //declaration

It need to be like this:

Source 1 :

extern const int global = 255; //a definition of global const variable in C++

Source 2 :

extern const int global; //declaration

From WikiBooks: C++ Programming‎ | Programming Languages‎ | C++‎ | Code‎ | Keywords

extern is required because const variables have internal linkage by default.

For functions too…

If you look at string.h, you will see that extern is used liberally throughout to declare the C functions, even though not strictly necessary

extern void *memccpy(void *, const void *, int, size_t);
extern void *memchr(const void *, int, size_t) __ATTR_PURE__;
extern int memcmp(const void *, const void *, size_t) __ATTR_PURE__;
extern void *memcpy(void *, const void *, size_t);
extern void *memmem(const void *, size_t, const void *, size_t) __ATTR_PURE__;
extern void *memmove(void *, const void *, size_t);

From WikiBooks: C++ Programming‎ | Programming Languages‎ | C++‎ | Code‎ | Keywords

 

extern void f();

declares that there is a function f taking no arguments and with no return value defined somewhere in the program; extern is redundant, but sometimes considered good style.

See also this answer to Effects of the extern keyword on C functions

Technically, every function in a library public header is ‘extern’, however labeling them as such has very little to no benefit, depending on the compiler. Most compilers can figure that out on their own. As you see, those functions are actually defined somewhere else.

Links

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s