Question

I have trouble finding solutions to reusing common custom-defined functions such as isPrime, isEven, etc. I know I will be reusing them over and over, but I do want to avoid writing them again and again inside each .cpp file. I looked into using a header file to contain all these functions, but I also heard the comment that the function will be compiled along with other functions in the header as well. So, as the number of custom functions increases, the compilation time gets longer.

Also, I want to avoid adding many individual files like isPrime.cpp, isEven.cpp, etc.

How should I reuse these functions efficiently? Please show a simple template for how each file is organized.

Thanks.

Was it helpful?

Solution

There are about four things that are "obvious" solutions. There may be others.

In order of "complexity":

  1. Add all the functions as inline functions in a header. This is fine if the functions are really tiny, but once they get big enough, this is not a good solution (because the functions may well get copied in many times in the same executable).

  2. Make one "functions.cpp" that contains a bundle of functions (suitably selected to belong together), and declare them in a "functions.h" - now you just need to link with one more file. Drawback is that ALL the functions in "functions.cpp" are being included in your final executable file, regardless of whether they are actually used or not (unless the compiler is very clever and can "kill" dead functions - most compilers don't do this).

  3. Make a library. In this case, you need one source file per function, which are compiled and built into a single library file, functions.a or functions.lib. Again, you need a header file (or several) to declare your functions, and then link with the library to include the functions into your executable. When the linker builds your final executable, each function that your executable "needs" is taken from the library, but other functions that you don't "need", will not be part of the executable file.

  4. Make a shared library. This is similar to building a library, except instead of including the code for the functions into your executable file, a separate "executable" shared library file (.dll, .dynlib or .so) will be created when you build your functions. When you use a shared library, you still need to give a "library" to the linker command, but the executable will only have a "stub" (or "thunk") that knows how to call the shared library code. This is really useful when you have something like cout or printf that almost every C++ program uses, and there are hundreds or thousands of programs on a machine, because all of these programs use the SAME printf or cout code, rather than having a copy each.

And if you thought adding 2-3 files to your commandline is a lot of work, I would suggest you stay away from using LLVM. These are the libraries that I add to build my compiler (fortunately, there is a tool to automatically do this):

-lLLVMLTO -lLLVMObjCARCOpts -lLLVMLinker -lLLVMipo -lLLVMVectorize -lLLVMBitWriter -lLLVMIRReader -lLLVMAsmParser -lLLVMTableGen -lLLVMDebugInfo -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMMCParser -lLLVMX86Desc -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMJIT -lLLVMLineEditor -lLLVMMCDisassembler -lLLVMInstrumentation -lLLVMInterpreter -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMProfileData -lLLVMMCJIT -lLLVMTarget -lLLVMRuntimeDyld -lLLVMExecutionEngine -lLLVMMC -lLLVMObject -lLLVMBitReader -lLLVMCore -lLLVMSupport

OTHER TIPS

You can have an header only file that includes the definition and declarations of the function (say for example functions.hpp), and include it whenever you use the functions (with #include "functions.hpp"):

// functions.hpp
void func() { … }

// main.cpp
#include "functions.hpp"
int main() {
    func();
}

Otherwise you can have an header file (again, for example, functions.hpp) in which you define the function signatures, and one file in which to define them (for example, function.cpp).

// functions.hpp
void func();

// functions.cpp
#include "functions.hpp"
void func() { … }

// main.cpp
#include "functions.hpp"
int main() {
    func();
}

In the latter, you'll have to compile functions.cpp and link the object file with main.cpp.

The common way to do it is to declare the methods in a header file, and then define them in another one. For instance, in common.hpp you could put:

bool isPrime(int number);
bool isEven(int number);

And then inside common.cpp you could put:

bool isPrime(int number) { ... }
bool isEven(int number) { ... }

And then you #include "common.hpp" to get access to those functions. Note that you can run into issues with multiple declarations of the same method if you don't use an include guard.

it is also a good idea to declare "#pragma once" in your header file. that way if your header files has been included in another header file, and the third file includes the second header file but also the first one, you will avoid multiple inclusions. If you are not using Visual Studio then do then write your header file contents in between #ifndef block:

#ifndef HEADER_FILE
#define HEADER_FILE

//your header file contents go here

#endif
// ------------------------
// utilities.h

bool isPrime( int );
bool isEven( int );

// ------------------------
// utilities.cpp

#include utilities.h
bool isPrime( int a ){ ... }
bool isEvent( int a ){ ... }

// ------------------------
// other.cpp

#include utilities.h

int main()
{
     isPrime( 2 );
     return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top