Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create wrappers to library functions with original name?

I found this question very interesting: How to force compilation error if function return value is not checked?

It's about enforcing compilation errors if you do not check the return value. I wrote an answer to that question where you can use gcc extensions like this:

__attribute__ ((warn_unused_result)) int foo (void) 
{
    return 5;
}

to enforce a warning and the compile with -Werror=unused-result to make the compiler generate an error if you don't use the return value somehow.

Now I would like to create wrapper functions to the regular standard functions. An idea is to rename them like this:

__attribute__ ((warn_unused_result)) realloc_wrapper(void *ptr, size_t new_size)
{
    return realloc(ptr, new_size);
}

But the problem is that this forces me to use a different name, which would cause a lot of search and replace. Granted, this can be done automatically, but still. Preferably, I would like to be able to create a header that I can use instead of a standard C header for any program. One use case is when debugging a big program. Then this would instantly point me to potential causes of bugs.

TL;DR

So in short, I want to be able to take this program:

#include <stdlib.h>

int main(void)
{
    char *ptr;
    realloc(ptr, 42);
}

and change it to:

// Replaced stdlib with a custom header
#include <mystdlib.h>

int main(void)
{
    char *ptr;
    realloc(ptr, 42);
}

and then the line with realloc should generate a warning.

I might add that I'm ok with a solution that isn't 100% perfect. The intended use is for debugging and not production code.

EDIT:

I just noticed that realloc was a bad choice, since it seems to already have this declaration by default, but I used PSkocik and made it work for fgets.

like image 223
klutt Avatar asked Oct 15 '19 13:10

klutt


People also ask

What is a wrapper function example?

Wrapper functions can be used to make writing computer programs easier. An example of this is the MouseAdapter and similar classes in the Java AWT library. Wrapper functions are useful in the development of applications that use third-party library functions.

What does it mean to create a wrapper?

In the context of software engineering, a wrapper is defined as an entity that encapsulates and hides the underlying complexity of another entity by means of well-defined interfaces.

What is the process of wrapping a piece of code in a function?

Encapsulation is the process of wrapping a piece of code in a function, allowing you to take advantage of all the things functions are good for.


1 Answers

A straightforward solution would be to shadow the function with an identically named macro. (I'll use puts as an example, because, as you've mentioned, realloc is already usually declared with warn_unused_result)

/*begin your header:*/

#include <stdio.h>

__attribute ((__warn_unused_result__)) static inline
int puts_wrapper(char const*X) 
{ 
   return (puts)(X); 
}
#define puts(X) puts_wrapper(X)

/*end your header*/

int main(void) { puts("hello, world"); }

(The parentheses around puts aren't necessary but they allow you to move the define before the puts_wrapper definition if you wanted to.)

Alternatively, you could simply redeclare the function with the warn_unused_result attribute added (works on both gcc and clang).

/*begin your header*/
#include <stdio.h>
__attribute ((__warn_unused_result__)) int puts(char const*);
/*end your header*/ 

int main(void) { puts("hello, world"); }
like image 80
PSkocik Avatar answered Oct 18 '22 20:10

PSkocik