Reputation: 35
Edit: The Question was meant as "is a function pointer atomic in the C standard".
Is a variable, which is a pointer to a function itself, thread-safe? With thread-safe, I mean, is the value always defined? Like, is it always a legal value, the address of an existing function? (Some function I assigned at some point to this value.)
I think storing the value in the variable should always be a single assembler instruction (similar to "reading"). Considering that, it should be fine, shouldn't it?
NOTE: I mean on a single core CPU. (I'm not sure if this makes a difference.)
Example, for code, set_a()
and do_something()
in the code below could be called from any thread at any time.
Test.h
typedef int fn_t (int a);
void set_a(fn_t * fn);
void do_something(void);
Test.c
static fn_t * a;
void set_a(fn_t * fn){
a = fn;
}
void do_something(void){
if (a != NULL && a(1) == 0){
printf(" Happend \n");
}
printf("Doing something else \n");
}
Upvotes: 1
Views: 130
Reputation: 181179
Is a variable, which is a pointer to a function itself, thread-safe? With thread-safe, i mean is the value always defined? Like is it always a legal value, a adr of a existing function.
No, regardless of threading. Neither object pointers nor function pointers are automatically guaranteed to contain addresses of valid targets. For example,
void (**p)(void) = malloc(sizeof(*p));
void (*fp1)(void) = (void (*)(void)) 0;
void (*fp2)(void) = (void (*)(void)) *p;
However, it is true that all functions live and keep the same address for the the entire run of the program, so once you take the address of an existing function, the result never becomes a dangling pointer.
It is also true that functions and their addresses are not thread-specific. A function pointer valid in one thread is also valid and points to the same function in any other thread in the same run of the program.
I think storing the value in the variable should always be a single assembler instruction (similar to "reading"). Considering that it sould be fine, shouldnt it?
That has little to do with thread safety, and it is not a special characteristic of function pointers. What you're asking seems more like whether accesses to objects of function pointer type are atomic. But at the level of the C language, that is not much related to how any given CPU implements reads and writes of values of that type. C has explicitly atomic types, but it does not recognize any accidentally atomic ones.
Example for code, set_a() and do_something() could be called from any thread at any time.
If one thread calls your set_a()
and a different one calls your do_something()
, without any synchronization between those calls, then the program contains a data race, and its behavior is undefined. This is true as long as the type of a
is not atomic, regardless of what its specific type is.
Upvotes: 1
Reputation: 27190
Is a variable, which is a pointer to a function itself, thread-safe?
You are asking the wrong question. It doesn't matter whether the variable is "thread-safe" (whatever that means*) or not. Your code uses the variable in a way that is not thread-safe.
This expression, a != NULL && a(1) == 0
first tests the value, and then uses the pointer. Nothing prevents some other thread from changing the value between the test and the use.
Thread-safe variables and objects do not magically confer thread-safety upon the code that uses them. A program as a whole is not "thread-safe" unless it is thread-safe at every level.
* If someone says that a variable is "thread-safe," they usually mean that no thread will ever see the variable contain any value other than its initial value or a value that the program stored in it. I don't know whether C pointer variables always have that property or not.
Upvotes: 1