extern and the XC8 C compiler

Perhaps I don't fully understand extern. With the XC8 C compiler, it seems like I can get away without using it.

In the file keypad.c I have a function signed char keypadGetPressedKeyLabel(void). In the header file keypad.h I have:

signed char keypadGetPressedKeyLabel(void);

I thought I would have to use extern, ie:

extern signed char keypadGetPressedKeyLabel(void);

The project builds without extern. And it works. Might this due to the fact that keypad.c and keypad.h are all part of the project? I'm using MPLABX.

• Are any other files using keypad.h? – Ignacio Vazquez-Abrams Nov 11 '14 at 20:05

extern is not strictly necessary for function prototypes in .h files - whether or not the function is actually used in one or many different .c files in your project.
Whether you have extern int foo(void); or just int foo(void); in your .h your compiler will read is as a function prototype either way.

Its necessary for global variables though since unlike functions they don't have prototypes.
So if you have an int thing; in one .c file and you want to use it in another .c file then you'll need an extern int thing; to tell the compiler that it does exist 'somewhere' in your project.

• Correct. Also, you can include initialization only on the definition of the variable e.g. int a = 0; it is an error to repeat this again in an external declaration e.g. extern int a = 0; // error – tcrosley Nov 11 '14 at 20:37

Functions are extern by default in C; that's why it works without the keyword.

• This is really the correct answer, but I think it would also benefit from a brief explanation of what extern actually means. – NickHalden Nov 11 '14 at 21:08
• Great answers; PICs XC8 compiler uses extern looking for external files, not just as a global declaration. – Leroy105 Jan 1 '17 at 18:04

extern is really a sign to the linker, that the symbol is defined in a different object file. As you only seem to have one object file, it doesn't make any difference whether it's there or not.

extern is largely obsolete for functions in other CUs in many of the smaller simpler compilers. If a symbol isn't found locally it will be searched for in other CUs and libraries. You provide a function prototype, but not the actual function, in the CU where you want to use it.

However, extern is required for variables that are shared between CUs. You can't define a prototype for a variable, so the extern keyword in this situation has to be used to create the variable equivalent of a function prototype.