14

my_math.h

// case 1 
unsigned int add_two_numbers(unsigned char a, unsigned char b);

//case 2 
extern unsigned int add_two_numbers(unsigned char a, unsigned char b); 

What is the difference between case 1 and case 2? I never used extern for function prototypes but looking at someone's code (who is way more experienced than I am) I see extern always used when declaring the function prototype. Can anyone point please point the difference? (or point me to a link where I can find specific information). Google says that is something related to the external linkage. Can anyone point me to an example where one would work and the other wouldn't?

I am using embedded C (KEIL), if it makes any difference.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
CalinTamaian
  • 269
  • 1
  • 3
  • 7

3 Answers3

17

extern is a linkage specifier for global linkage. Its counterpart is static, which specifies file-local linkage. Since global linkage is the default in C, adding extern to the declaration makes no difference for the declaration of a function. For a variable it prevents automatic memory allocation and using it is the only way to just declare a variable at global scope.

If you just google the keyword, you will find many articles e.g. this one: geeks for geeks

midor
  • 5,487
  • 2
  • 23
  • 52
2

I learned the following for variables years ago from an experienced programmer:

glo.h:
#ifndef EXTERN
#define EXTERN extern
#endif
...
EXTERN int gMyVar;
...

main.c:
#define EXTERN
#include "glo.h"

"glo.h" anywhere inlcuded will just declare all global variables. "glo.h" included in main.c will allocate the storage for the variables. I believe this method was common practice.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • 1
    Interesting approach, but to me it just seems more straightforward to just have a glo.c file with the variable declarations. No need for preprocessor directives. – jgoeders Nov 07 '18 at 04:07
  • @jgoeders, the approach requires the symbols to be declared only once. Yours requires them to be declared at least twice, which is error prone when renaming/adding/deleting symbols. Note that only in `main` is a `#define` required; all other files only need a `#include "glo.h"`. – Paul Ogilvie Nov 07 '18 at 09:11
  • I agree, your posted method does eliminate some duplication, although the .c/.h definition/declaration approach only has a single definition and single declaration, not more, so I'm not sure what you're suggesting by "at least twice". There is lots of discussion of both methods (and others) here https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files – jgoeders Nov 07 '18 at 15:08
  • "At least twice" means there is at least one time an `extern int myvar;` declaration and exactly one `int myvar;` definition. My schme is described verbatim in your linked question under the header "Avoiding Code Duplication" (which is exactly my point). – Paul Ogilvie Nov 07 '18 at 15:14
1

For a (non-inline) function, it doesn't make any difference, extern is implicit if no storage-class specifier is given (note, that this applies only to functions, objects are different), so it's only a matter of style what you use.

I've seen both (never use extern for functions/only use it for the declarations in the header), maybe some use extern for symmetry with object identifiers, or to make it easier to grep for external symbols.

Choose whatever you prefer and stay consistent, it doesn't make a difference.

mafso
  • 5,433
  • 2
  • 19
  • 40