Well, the first point is the declaration of the void pointer that is wrong.
It should not be:
_Atomic void* ptr = NULL;
But
void * _Atomic ptr = NULL;
The last one will give you the correct response.
Remember that the definitions in C must be read from left to right, in the second case we have that
ptr is an atomic variable that holds a pointer to
void.
In PellesC
atomic_is_lock_free() is a macro defined as:
/*
* atomic_is_lock_free generic function
*/
#define atomic_is_lock_free(X) (_Bool)(_Generic(*X, \
_Bool : 1, \
char : 1, \
char signed : 1, \
char unsigned : 1, \
short : 1, \
short unsigned : 1, \
int : 1, \
int unsigned : 1, \
long : 1, \
long unsigned : 1, \
long long : 1, \
long long unsigned : 1, \
char16_t : 1, \
char32_t : 1, \
wchar_t : 1, \
void* : 1, \
default : 0))
Substantially any base type which have a size accessible using a locking processor instruction is free from interlock. All others are not.
Your original declaration stated that
ptr was a common pointer to void, the last eventually atomic, defaulting to false.
You would eventually test:
int main(void)
{
void * _Atomic ptr = NULL;
printf("atomic_is_lock_free(void*):%s\n",
atomic_is_lock_free(&ptr) ? "true" : "false");
_Atomic uintptr_t uptr = 0;
printf("atomic_is_lock_free(uintptr_t):%s\n",
atomic_is_lock_free(&uptr) ? "true" : "false");
_Atomic struct atom{int a; int b;}; //Make compiler happy and break declaration. See note below
struct atom AtomStruct = {0};
printf("atomic_is_lock_free(structure):%s\n",
atomic_is_lock_free(&AtomStruct) ? "true" : "false");
return 0;
}
Note: Just discovered that the generic
atomic_store() function doesn't like nameless structures as in:
_Atomic struct {int a; int b;} AtomStruct = {0};
And this maybe is a bug...