I want to interpose a library function from a third party, using LD_PRELOAD, and I have seen the following code pattern in a lot of places:
void interposed_func()
{
static void(*real_func)() = NULL;
if (real_func == NULL)
real_func = (void(*)())dlsym(RTLD_NEXT, "interposed_func");
real_func();
}
It calls to my attention that if at each call of the function. What's wrong with just:
void interposed_func()
{
static void(*real_func)() = (void(*)())dlsym(RTLD_NEXT, "interposed_func");
real_func();
}
Since real_func is a static function local variable it will only be initialized once right? I don't understand why all of the examples I have faced uses an additional but (in my view) unnecesary if. Is there any else to consider that I'm not aware of?
Objects with static storage duration (i.e. those declared at file scope or with the
statickeyword) may only be initialized with a constant expression, as such initialization effectively happens at compile time.Your second example does not qualify because a function call is not a constant expression. It would be the same as trying to initialize a file scope variable with a function call.
The first example is required to satisfy the requirement of a constant initializer. The overhead of a NULL check on each access is minimal.
Also, the conversion on this line:
Is technically not allowed by the C standard, as it converts an object pointer to a function pointer. The proper conversion would be this:
As noted in the man page for
dlsymin an example: