Home > front end >  how to not include certain functions in a header file for use in C programing
how to not include certain functions in a header file for use in C programing

Time:06-21

To paint the picture let's imagine we have a header called headertest.h and where going to use it in a file called test.c

It's context look like this

#include <stddef.h>

extern size_t string_lenght(const char *);

size_t string_lenght(const char *str)
{
    size_t n = 0;
    while (str[n] != '\0')
        n  ;
    return (n);
}

It's purpose is to count the lenght of a given string and give output as size_t

if we include it in our test.c file like this and compile with gcc -o test test.c

#include "<location to header>/headertest.h"
    
int main ()
{
   
}

it compiles successfully and by running the command du -b test | awk '{print $1}' it outputs 16504, telling us it's size is 16504 bytes. However if we comment #include and just leave int main () and recompile test and run the same command again, we get 16464.

so in conclusion, how do you tell C to specifically only include a function when compiling only if it's present in the main C program, from a self made header file.

CodePudding user response:

Solutions from article mentioned in comments are pretty good, but they have their own quirks:

  • static works great for private stuff, but makes little sense for things that may be directly called from more than one .c file
  • smarter things like lto, or linker garbage collection require compiler/linker support and each impose their own quirks/cons

Libraries often use macros to explicitly disable/enable certain features. The advantages are:

  • simplicity and portability
  • unused code isn't even compiled, so you can also reduce build time
  • less dependencies if feature requires extra lib
  • it also allows for switching functionality that isn't separate function (e.g. param validation)

Example:

// file mylib.h
#ifndef MYLIB_FOO_OFF // ifndef - "if macro not defined"
 void mylib_foo();
#endif

#ifndef MYLIB_BAR_OFF
 #include <otherlib.h>
 void mylib_foo(otherlib_struct s);
#endif

// file mylib.c
#include "mylib.h"

#ifndef MYLIB_FOO_OFF
 void mylib_foo() { /* implementation */ };
#endif

#ifndef MYLIB_BAR_OFF
 void mylib_foo(otherlib_struct s) { /* implementation */ }
#endif

Then if you don't need mylib_bar() you can just instruct your's compiler/build system to define MYLIB_BAR_OFF, e.g gcc -DMYLIB_BAR_OFF main.c mylib.c. Preprocessor will then remove code within #ifndef directives scope, as if it wasn't typed in the first place

Example from real world library: https://www.sqlite.org/compile.html#overview

CodePudding user response:

It is not uncommon to use pre-compiler defines in a header file to exclude code for one OS or another...

#ifdef __linux__ 
    void Do_one_thing(void);
#elif _WIN32
    void Do_another_thing(void);
#else __APPLE__
    void Do_yet_another_thing(void);
#endif
  • Related