Today, someone filed:
6457949 atomic_cas_ptr signature is broken
using bugs.opensolaris.org. I've just closed it as "Not a Defect", and
attempted to contact the submitter to let him know why. Unfortunately,
the Yahoo e-mail address he used is defunct. So I thought I'd pass this
along for the record.
Interestingly, I was one of the code-reviewers for wad which introduced
the atomics, and I had the same reaction as the filer did to the type of
atomic_cas_ptr()'s argument.
Below is the text I added to the bug report.
(thinking about it further, 'volatile void **' is incorrect anyway;
that's a pointer to a pointer to a volatile void. We'd want
'void * volatile *' or something, which would still get us into
casting-hell)
Cheers,
- jonathan
In C, "void *" is a generic pointer. "void **" is a pointer to a generic
pointer, *not* a generic pointer to a generic pointer. It's unfortunate,
but that's how the C standard works.
If we had used your formulation of the function signature, we would
need to add casts to avoid compiler warnings, and the casts that we have
to do are technically not kosher:
% cat > tmpc.c <<EOF
#include <atomic.h>
#include <stdio.h>
extern void *matt_atomic_cas_ptr(volatile void **, void *, void *);
int
main(int argc, char *argv[])
{
int *ptr = NULL;
int val = 1;
printf("ptr value: %p\n", ptr);
(void) matt_atomic_cas_ptr(&ptr, NULL, &val);
return (0);
}
EOF
% gcc -O4 -Wall -c tmpc.c
tmpc.c: In function `main':
tmpc.c:14: warning: passing arg 1 of `matt_atomic_cas_ptr' from incompatible
pointer type
% cat > tmpc.c <<EOF
#include <atomic.h>
#include <stdio.h>
extern void *matt_atomic_cas_ptr(volatile void **, void *, void *);
int
main(int argc, char *argv[])
{
int *ptr = NULL;
int val = 1;
printf("ptr value: %p\n", ptr);
(void) matt_atomic_cas_ptr((volatile void **)&ptr, NULL, &val);
return (0);
}
EOF
% gcc -c -O4 -Wall -o tmpc tmpc.c
tmpc.c: In function `main':
tmpc.c:14: warning: dereferencing type-punned pointer will break strict-aliasing
rules
--- cut here ---
As it is, atomic_cas_ptr() can be used to CAS pointer values without any extra
casts:
--- cut here ---
#include <atomic.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{
int *ptr = NULL, *oldptr;
int val = 1;
printf("ptr value: %p\n", ptr);
oldptr = atomic_cas_ptr(&ptr, NULL, &val);
printf("ptr %p oldptr %p &val %p\n", ptr, oldptr, &val);
return (0);
}
--- cut here ---
This compiles without warnings. The simple truth is that, in ANSI C,
the best generic "pointer to volatile pointer" type is "volatile void
*", which is why we picked it.
I'm closing this bug as "Not a Defect".
_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code