In C
, is there a way to ensure a function is called only once without using pthread_once
?
The following works in C++
but apparently not in C
because initialization of a static variable must be to a constant (as I interpret the compile error)
// main.c
int func()
{
return 42;
}
int main( int argc, char* argv[] )
{
static int i = func();
return 0;
}
I thought using the comma operator might get around this, but that doesn't work either:
// main.c
int func()
{
return 42;
}
int main( int argc, char* argv[] )
{
static int i = ( func(), 42 );
return 0;
}
Compilation of both results in the following compile error:
> gcc -g main.c
main.c: In function 'main':
main.c:10:18: error: initializer element is not constant
Are there any ways to circumvent this and ensure a function is only invoked once (from a calling function scope) without using pthread_once
?
To be specific, I don't want to return early from func()
if it has been called once, I'm interested in compile-time assurance that func()
is only called once from a calling function scope - i.e. similar to how C++
would handle the above code.
(In other words, the above code is legal to a C++
compiler, which ensures func()
is only called once - is there an equivalent way to do this in C
without pthread_once
?)
EDIT:
I didn't phrase this ideally in the original post: I was looking for a solution that didn't involve wrapper/helper functions or variables; i.e. I was curious to know if there was a construct in the C
language that allowed this situation to be handled equivalently to how it is handled in C++
. jxh's solution fits that best, making use of a gcc
extension.
Your attempt to leverage static variable initialization will not work. C only allows static
variable to be initialized with constants, so a function call is out.
It is not clear why you want the onetime call, but if it's okay to do it at program startup, there is a GCC specific solution.
You can assign the constructor
attribute to the function.
#include <stdio.h>
__attribute__((constructor))
void func()
{
puts(__func__);
}
int main () {}
This suggestion does not perform your specific ask:
I'm interested in compile-time assurance that func() is only called once from a calling function scope ...
Instead, it assures the function is called exactly once when the program starts (or when the library it is a part of is loaded).
If you need to control when the function is called in the exact way initialization of a static variable local to a function is initialized, then you could use a static variable to track whether your one shot function has been called yet with its own static variable. Other answers have already described how to accomplish this, but for completeness:
void caller_of_func()
{
static bool func_already_called;
if (!func_already_called) {
func();
func_already_called = true;
}
/*...*/
}
Another way to accomplish your goal would be to call the function through a function pointer. The initial call to the function would do the real work, and then switch the function pointer to point to a function that does nothing.
void nothing_func(int *x);
void initial_func(int *x);
void (*func)(int *x) = initial_func;
void initial_func(int *x) {
*x = 42;
puts(__func__);
func = nothing_func;
}
void nothing_func(int *x) {
puts(__func__);
}
void foo(void) {
static int x;
func(&x);
printf("%s: %d\n", __func__, x);
++x;
}
int main(void) {
foo();
foo();
}