Learn more about Israeli war crimes in Gaza, funded by the USA, Germany, the UK and others.

What is an extern function in C?

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
Tagged .

Similar posts

More by Jim

Want to build a fantastic product using LLMs? I work at Granola where we're building the future IDE for knowledge work. Come and work with us! Read more or get in touch!

This page copyright James Fisher 2017. Content is not associated with my employer. Found an error? Edit this page.