extern
functions
Earlier I showed the C extern
keyword applied to variable declarations.
More generally, extern
can be applied to declarations.
There are two kinds of thing you can declare in C: variables and functions.
So the extern
keyword can also be applied to function declarations.
For example:
extern int incr(int);
extern int add(int a, int b) { return a+b; }
Applied to a function declaration, the extern
keyword in fact does nothing:
the declaration extern int incr(int)
is exactly the same as int incr(int)
.
This is because all function declarations have an implicit extern
applied!
This also applies to function definitions:
the function definition int incr(int x) { return x+1; }
is implicitly extern int incr(int x) { return x+1; }
.
So, you have been using extern
, whether you knew it or not.
For this reason, the following program yields an ugly linker error instead of a compiler error:
#include <stdio.h>
int incr(int);
int main() {
printf("incr(5) = %d\n", incr(5));
}
$ clang main.c
Undefined symbols for architecture x86_64:
"_incr", referenced from:
_main in main-b06e2c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Why is it the case that all C function declarations are implicitly extern
?
If it were possible to declare a C function without making it extern,
the above program could generate a higher-level compiler error, like this:
$ clang main.c
main.c:2:1: error: function 'incr' declared but not defined
int incr(int);
In fact, it is possible to declare a non-extern
function,
and it is done with the static
keyword:
#include <stdio.h>
static int incr(int);
int main() {
printf("incr(5) = %d\n", incr(5));
}
$ clang main.c
main.c:2:12: warning: function 'incr' has internal linkage but is not defined [-Wundefined-internal]
static int incr(int);
^
main.c:4:28: note: used here
printf("incr(5) = %d\n", incr(5));
In effect, static
undoes the work of the implicit extern
.
In my opinion this is a flaw in the C language.
The semantics should be the same as with C variables:
default to non-external; become external when extern
is applied.
The static
keyword then becomes unnecessary.
externed? | |
---|---|
int incr(int); |
yes, but this is a language flaw |
extern int incr(int); |
yes |
static int incr(int); |
no, but this shouldn’t be necessary |
static extern int incr(int); |
this is not possible |
I wrote this because I felt like it. This post is my own, and not associated with my employer.
Jim. Public speaking. Friends. Vidrio.