How to create wrappers to library functions with original name?

Viewed 112

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.

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"); }
Related