Search code examples
c++reusability

How to reuse functions (such as isPrime, isEven, isPalindrome) in c++


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.


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