RBF06
RBF06

Reputation: 2419

How do you define functions in header files?

The setup

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();
}

The Problem

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

Answers (3)

Mickael B.
Mickael B.

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

Sy Love
Sy Love

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

C_Elegans
C_Elegans

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

Related Questions