27

I'm getting started with C programming. I currently have a large file that contains a lot of functions. I would like to move these functions to a separate file so that the code is easier to read. However, I can't seem to figure out how to properly include/compile and can't find an example in any online tutorials that I've found. Here's a simplified example:

#include <stdlib.h>
#include <stdio.h>

void func1(void) {
  printf("Function 1!\n");
}

void func2(void) {
  printf("Function 2!\n");
}

int main(void) {
  func1();
  func2();
  return 0;
}

How do you move C functions into a separate file? FYI: I'm using gcc.

Update: These answers are very helpful, thank you. Now it seems that my simplified example is not good enough because I realized the reason my program failed to compile is because I'm using a global variable in my functions.

#include <stdlib.h>
#include <stdio.h>

int counter = 0;

void func1(void) {
  printf("Function 1!\n");
  counter++;
}

int main(void) {
  func1();
  return 0;
}

Moving these functions to an external file doesn't work because they need to reference this global variable:

#include <stdlib.h>
#include <stdio.h>
#include "functions.c"

int counter = 0;

int main(void) {
  func1();
  counter = 100;
  return 0;
}

How can I get around this issue?

Andrew
  • 227,796
  • 193
  • 515
  • 708
  • Just cut-and paste the function definitions into another file, then create a header with the function declarations. You'll need to include this header into your file that uses `main()`. You'll now need to compile and link each source file together, by writing something like `gcc -o program main.c functions.c`. –  Nov 01 '13 at 18:26
  • 2
    See: [What is a good reference documenting patterns of use of `.h` files in C?](http://stackoverflow.com/questions/256277) and [Should I use `#include` in headers?](http://stackoverflow.com/questions/1804486) for related information. – Jonathan Leffler Nov 01 '13 at 18:43
  • I suppose I should also point to what used to be called [What are `extern` variables in C?](http://stackoverflow.com/questions/1433204/how-do-i-share-a-variable-between-source-files-in-c-with-extern-but-how/), which is primarily focussed on variables rather than functions, but also contains (a lot of) information, much of it useful. – Jonathan Leffler Nov 01 '13 at 18:53

4 Answers4

38

Okay. Here we go.

Your main.c file

#include <stdlib.h>
#include <stdio.h>
#include "functions.h"

int main(void) {
  func1();
  func2();
  return 0;
}

Your functions.h file

void func1(void);
void func2(void);

Your functions.c file

#include "functions.h"

void func1(void) {
  printf("Function 1!\n");
}

void func2(void) {
  printf("Function 2!\n");
}

Compile it with:

gcc -o main.exe main.c functions.c
cyclaminist
  • 1,697
  • 1
  • 6
  • 12
Raju Kunde
  • 982
  • 1
  • 8
  • 18
  • Thanks for a full example. It seems that creating a header file is unnecessary if I can just `#include "functions.c"`. Why would I create a header file? – Andrew Nov 01 '13 at 18:44
  • 2
    You'd create the header because in general you have more than one source file using the functions (so as well as `main.c` there is also `aux.c` and ...) and they can't all use the `#include "func1.c"` trick; only one of the source files can do that, but the others still need the function declarations, so you need a header. – Jonathan Leffler Nov 01 '13 at 18:49
  • 1
    yes. but, its a good practise to include the header file's, so that your global declarations all goes there and your code looks good.ans also agree with Jonathan Leffler. – Raju Kunde Nov 01 '13 at 18:53
  • 1
    @user1940987 It is a good idea to include the header files, but it is bad to have the header file include the source file since that defeats the purpose of having a separate header file. – David M. Syzdek Nov 01 '13 at 18:57
  • 1
    In your example you include the function prototypes after the function definitions which, in most cases, makes even creating a function prototype moot. – David M. Syzdek Nov 01 '13 at 19:18
  • if you include the .c file you will get multiple copies of the functions. Many toolchains will not permit that, if you have lots of .c files including the same .c file(s) the linker will complain. Plus its an overhead, you will compile the source of func1 many times – pm100 Apr 03 '18 at 21:46
12

The most common way is to place your function prototypes in a header file and your function implementations in a source file. For example:

func1.h

#ifndef MY_FUNC1_H
#define MY_FUNC1_H
#include <stdio.h>

// declares a variable
extern int var1;

// declares a function
void func1(void);
#endif

func1.c

#include "func1.h"

// defines a variable
int var1 = 512;

// defines a function
void func1(void) {
    printf("Function 1!\n");
}

func2.h:

#ifndef MY_FUNC2_H
#define MY_FUNC2_H
#include <stdio.h>
void func2(void);
#endif

func2.c:

#include "func1.h" // included in order to use var1
#include "func2.h"
void func2(void) {
    printf("Function 2 with var1 == %i\n", var1);
}

main.c:

#include <stdio.h>
#include "func1.h"
#include "func2.h"

int main(void) {
    var1 += 512;
    func1();
    func2();
    return 0;
}

You would then compile using the following:

gcc -c -o func1.o func1.c
gcc -c -o func2.o func2.c
gcc -c -o main.o  main.c
gcc -o myprog main.o func1.o func2.o
./myprog

I only placed one function in each source/header pair for illustration. You could create just one header which includes the prototypes for all of the source files, or you could create multiple header files for each source file. The key is that any source file which will call the function, needs to include a header file which includes the function's prototype.

As a general rule, you only want a header file included once, this is the purpose of the #ifndef #define #endif macros in the header files.

David M. Syzdek
  • 15,360
  • 6
  • 30
  • 40
  • Thanks! I added an update which mentions global variables. How would I deal with those? – Andrew Nov 01 '13 at 19:09
  • Note that neither `func1.h` nor `func2.h` needs to include `` to make the declarations in the file compile, so the nested include should be left out. Headers should be idempotent (like yours are, because of the header guards) and self-contained. Yours are self-contained too, but they include unnecessary headers which is sub-optimal. See [Should I us e`#include` in headers?](http://stackoverflow.com/questions/1804486) – Jonathan Leffler Nov 01 '13 at 20:26
  • @JonathanLeffler While technically true, I've found it is better to include the header files required to preprocess the the new header than requiring the sources files which call it to do so. A great example of this would be including stdint.h for using specific width types such as uint32_t and uint64_t. – David M. Syzdek Nov 01 '13 at 21:05
  • If the functions in the header use types from ``, then you should include `` in the header. Your headers should be both self-contained and idempotent. This is the self-containment requirement: you should be able to use the header without having to include anything else. Idempotence is achieved by the header guards; including the header twice (deliberately, or more usually coincidentally or by accident) should not cause problems. See the postings linked to previously for the details. – Jonathan Leffler Nov 01 '13 at 21:24
6

First you have to learn the difference between a declaration and definition. A declaration tells the compiler that something, like a function, exists. A definition is, for the case of functions, the actual function implementation.

So what you do is move the definition to another file, but add a declaration in the file where the function is to be called. You then build both files together, and the compiler and linker will take care of the rest.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
-2

You can do something like this.

    /* func1.c */
    void func1(void) {
      printf("Function 1!\n");
    }

    /* func2.c */
    void func2(void) {
      printf("Function 2!\n");
    }

    /* main.c */
    #include "func1.c"
    #include "func2.c"

    int main ( void )
    {
    func1();
    func2();
    return 0;
    }
Douglas Franco
  • 591
  • 5
  • 13
  • Interesting...this works too (without needing a header file). Why is that? – Andrew Nov 01 '13 at 18:43
  • 3
    -1: Sorry, but...Including `.c` source files is feasible in some cases, but not sensible in most cases. (It works here, but cannot be recommended even though it works.) Specifically, if you had two files, `main.c` and `aux.c` (parts of the same program) that both needed to use `func1()` and `func2()`, you could not use this technique in both files. You'd need a header to declare the functions for use in at least one of the files `main.c` and `aux.c`. Of course, you should have the header and include it in all of the source files (`main.c`, `aux.c`, `func1.c` and `func2.c`). – Jonathan Leffler Nov 01 '13 at 18:45