Reputation: 2419
If I have a program like this
A header file that declares my main library function, primary()
and defines a short simple helper function, helper()
.
/* primary_header.h */
#ifndef _PRIMARY_HEADER_H
#define _PRIMARY_HEADER_H
#include <stdio.h>
/* Forward declare the primary workhorse function */
void primary();
/* Also define a helper function */
void helper()
{
printf("I'm a helper function and I helped!\n");
}
#endif /* _PRIMARY_HEADER_H */
The implementation file for my primary function that defines it.
/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>
/* Define the primary workhorse function */
void primary()
{
/* do the main work */
printf("I'm the primary function, I'm doin' work.\n");
/* also get some help from the helper function */
helper();
}
a main()
file that tests the code by calling primary()
/* main.c */
#include "primary_header.h"
int main()
{
/* just call the primary function */
primary();
}
Using
gcc main.c primary_impl.c
does not link because the primary_header.h
file gets included twice and therefore there is an illegal double definition of the function helper()
. What is the correct way to structure the source code for this project such that double definitions do not happen?
Upvotes: 6
Views: 46918
Reputation: 5215
You should only write your function's prototype in the header file, the body of your function should be written in a .c file.
Do this :
primary_header.h
/* primary_header.h */
#ifndef PRIMARY_HEADER_H
#define PRIMARY_HEADER_H
#include <stdio.h>
/* Forward declare the primary workhorse function */
void primary(void);
/* Also define a helper function */
void helper(void);
#endif /* PRIMARY_HEADER_H */
primary_impl.c
/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>
/* Define the primary workhorse function */
void primary()
{
/* do the main work */
printf("I'm the primary function, I'm doin' work.\n");
/* also get some help from the helper function */
helper();
}
void helper()
{
printf("I'm a helper function and I helped!\n");
}
Edit: change _PRIMARY_HEADER_H
to PRIMARY_HEADER_H
. As @Jonathan Leffler and @Pablo said, underscore names are reserved identifiers
Upvotes: 15
Reputation: 21
You can define a function in header files if it's weak linkage like:
// test.h
__attribute__((weak)) int test() {
static int s = 0;
return s++;
}
// a.c
#include "test.h"
#include <stdio.h>
void a(){
print("%d", test());
}
// b.c
#include "test.h"
#include <stdio.h>
void b(){
print("%d", test());
}
// main.c
#include "test.h"
#include <stdio.h>
void a();
void b();
void main(){
a();
b();
print("%d", test());
}
cc a.c b.c main.c
won't raise multiple definitions error and the output should be 012
as expected, meaning a.c
, b.c
and main.c
share the same test
function.
You can achieve the same result in c++ by using inline
.
Moreover, weak linkage can also be used on variable definition, allowing you to define and initialize a global variable in header files without source files (similar to inline static
in c++).
Note:
Weak symbols are not mentioned by the C or C++ language standards.
So be careful when using it in c. But in c++, inline
and inline static
are portable form c++11 and c++17.
Upvotes: 2
Reputation: 1133
You almost never write a function inside a header file unless it is marked to always be inlined. Instead, you write the function in a .c
file and copy the function's declaration (not definition) to the header file so it can be used elsewhere.
Upvotes: 10