Search code examples
cscopeexternstorage-class-specifier

Why do I need to declare this function extern. It works without it


I am new to the concept of extern. Today at work I came across a large number of extern functions that were declared inside of header file; foo.h. Somewhere off in a mess of folders I found a foo.c file that contained the definition of said functions but it did not #include foo.h. When I got home I decided to play around with the extern storage class examples. After doing some reading in the "C book" this is what I came up with.

Here is what I DID NOT expect to work. But it did.

main.c

#include <stdio.h> 

int data;

int main()
{

  data = 6;

  printf("%d\n", getData());

  data = 8;

  printf("%d\n", getData());
  return 0;
} 

externs.c

int getData()
{
  extern int data;
  return data;
}

bash

gcc main.c externs.c -o externs

I didn't think this would work because the function is not technically (or at least verbose) defined before main. Does this work because the default storage class for int getData() is extern? If so, why even bother with the following example (similar to what I saw at work)?

main2.c

#include <stdio.h> 
#include "externs.h"

int data;

int main()
{

  data = 6;

  printf("%d\n", getData());

  data = 8;

  printf("%d\n", getData());
  return 0;
} 

externs.h

#ifndef _EXTERNSH_
#define _EXTERNSH_

extern int getData();

#endif

externs.c

int getData()
{
  extern int data;
  return data;
}

bash

gcc main2.c externs.c -o externs

Solution

  • Functions are implicitly extern. You can change this by declaring them as static.

    You are right that it is redundant to say extern int getData(); compared to int getData(); but some people feel that it improves code clarity.

    Note that since C99, your first example is ill-formed. It calls getData without that function having been declared. In C89 this performed an implicit int getData(); declaration, but since C99 that was removed. Use the compiler switches -std=c99 -pedantic to test this.