Adwaith R Krishna
Adwaith R Krishna

Reputation: 892

How to create a header like a standard library header, so that program can be compiled without linking all object files of functions in the header?

Am trying to create a header file which can be included like #include "sort.h "
and the program in which the header is included can be compiled normally
g++ main.cpp
without having to link every single object file of functions in the header with the main.

g++ -c main.cpp insertion_sort.cpp merge_sort.cpp


g++ main.o merge_sort.o insertion_sort.o

so do I have to link every single object file for every single function in the header. or is their another way?
header file:

//sort.h file
#ifndef sort_h
#define sort_h

    void insertion_sort(int *a,int n);
    void merge_sort(int *a,int n);

    //I want to include more functions

    #endif

How to use my header like a normal header like cmath or stdlib.h?

Upvotes: 2

Views: 215

Answers (2)

Jesper Juhl
Jesper Juhl

Reputation: 31447

You seem to be under the impression that things you get from standard library headers don't have corresponding object files/library files that need to be linked in. This is wrong.

The standard library is linked to your application, it's just that the compiler does it automatically for you. You don't have to tell it manually to do so.

Your application also needs the standard library available in order to run. This is why you have to install the Microsoft redistributables on a machine where you want to run a program built with Visual Studio for example. Other compilers have similar requirements that you need to distribute their run-time libraries along with your application.

In short; the standard library is no different from other libraries, except for the fact that the compiler links it in for you behind the scenes.

Upvotes: 3

eozd
eozd

Reputation: 1193

You can write template functions entirely composed of header files. Then, you don't need any .cpp files and don't need to link to object files. Although this is not a direct solution to the asked question, it is a way of "not linking every single object file for every function".

Putting All Together

If we give an example, you may try changing your sort.h file as follows

//sort.h file
#ifndef sort_h
#define sort_h

    template <typename T>
    void insertion_sort(T* a,int n) {
        // insertion sort implementation goes here
    }

    template <typename T>
    void merge_sort(T* a,int n) {
        // merge sort implementation goes here
    }

#endif

When you write your sorting routines as template functions here, your function must be generic enough to accomodate for generic T types. In general, for sorting routines, T must be less-than comparable.

Separate Interface and Implementation

If you don't like to put documentation, interface and implementation all in one place, you may declare the function first together with its documentation. Then, you may define it below or possibly in some other file. So, the following is also possible:

//sort.h file
#ifndef sort_h
#define sort_h

    /**
     *  Function documentation
     */
    template <typename T>
    void insertion_sort(T* a,int n);

    /**
     *  Function documentation
     */
    template <typename T>
    void merge_sort(T* a,int n);


#include "insertion_sort.h"
#include "merge_sort.h"
#endif

//insertion_sort.h file
#ifndef insertion_sort_h
#define insertion_sort_h

    template <typename T>
    void insertion_sort(T* a, int n) {
        // insertion sort implementation goes here
    }

#endif

//merge_sort.h file
#ifndef merge_sort_h
#define merge_sort_h

    template <typename T>
    void merge_sort(T* a, int n) {
        // merge sort implementation goes here
    }

#endif

Some people like to call template header implementation files .tpp files. This depends on your preference.

Using From main.cpp

You can use the first or the second options from main.cpp as follows:

//main.cpp
#include "sort.h"
#include <vector>

int main() {
    std::vector<int> vec_int;
    // fill vector

    insertion_sort(&vec_int[0], vec_int.size());

    std::vector<double> vec_double;
    // fill vector

    merge_sort(&vec_double[0], vec_double.size());
}

Compiling

Since we didn't use any cpp files, now compiling main.cpp should be as simple as

g++ -Wall -Wextra -g main.cpp

assuming that main.cpp and our header files are in the same directory. If header files are in some directory named include, then we compile with

g++ -Wall -Wextra -g -Iinclude main.cpp

Upvotes: 2

Related Questions