如何创建具有原始名称的库函数包装器?
我发现这个问题非常有趣:如果未检查函数返回值,如何强制编译错误?
I found this question very interesting: How to force compilation error if function return value is not checked?
这是关于如果不检查返回值则强制执行编译错误.我写了这个问题的答案,您可以在其中使用gcc扩展名:
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;
}
强制执行警告,并使用-Werror=unused-result
进行编译,如果您不以某种方式使用返回值,则会使编译器生成错误.
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);
}
但是问题是,这迫使我使用其他名称,这将导致大量搜索和替换.当然,这可以自动完成,但仍然可以.最好,我希望能够创建一个我可以使用的头文件,而不是任何程序的标准C头文件.一种用例是调试大型程序时.然后,这会立即使我指出潜在的错误原因.
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.
因此,简而言之,我希望能够参加此计划:
So in short, I want to be able to take this program:
#include <stdlib.h>
int main(void)
{
char *ptr;
realloc(ptr, 42);
}
并将其更改为:
// Replaced stdlib with a custom header
#include <mystdlib.h>
int main(void)
{
char *ptr;
realloc(ptr, 42);
}
,然后带有realloc
的行将生成警告.
and then the line with realloc
should generate a warning.
我可能会补充说,我认为解决方案并非100%完美.预期用途是用于调试,而不是生产代码.
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.
我只是注意到realloc
是一个错误的选择,因为默认情况下它似乎已经具有此声明,但是我使用了PSkocik并使它适用于fgets
.
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
.
一个简单的解决方案是用一个具有相同名称的宏对函数进行屏蔽. (我将使用puts
作为示例,因为正如您已经提到的,realloc
通常已经用warn_unused_result
声明了)
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"); }
(不需要在puts
周围加上括号,但如果需要,它们可以使您将定义移到puts_wrapper
定义之前.)
(The parentheses around puts
aren't necessary but they allow you to move the define before the puts_wrapper
definition if you wanted to.)
或者,您可以简单地在添加了warn_unused_result
属性的情况下重新声明该函数(适用于gcc和clang).
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"); }