是否可以安全地假设pid_t始终是int类型(如标准中所定义)?

时间:2019-05-28 15:22:03

标签: c macos compare-and-swap

我想自动比较和交换pid_t变量。我读的是标准的int类型。

我知道,atomic_compare_exchange_strong_explicit()可以自行管理。我需要做的就是将类型设置为_Atomic(pid_t)。

但是当我在macOS上工作时,我也想使其与OSX旧库兼容,libkern/OSAtomic.h需要知道CAS的类型和类型。

就像是size_t一样,我可以简单地这样做,

#   ifdef __LP64__
#       define CAS_size_t(old, new, mem) \
        OSAtomicCompareAndSwap64((int64_t) (*old), (int64_t) (new), (volatile int64_t *) (mem))
#   else
#       define CAS_size_t(old, new, mem) \
        OSAtomicCompareAndSwap32((int32_t) (*old), (int32_t) (new), (volatile int32_t *) (mem))
#   endif

但是对于pid_t,我不确定,因为即使未定义__LP64__,它也可能是int64_t,int32_t,int16_t还是什么?

1 个答案:

答案 0 :(得分:3)

只需检查宏内部值的大小:

#define OSAtomicCompareAndSwap(old, new, mem)  do{ \
     if (sizeof(*old) == sizeof(int32_t)) { \
        OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem));  \
     } else if (sizeof(*old) == sizeof(int64_t)) { \
        OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem));  \
     } else assert(0); }while(0)

无论如何,应该由编译器优化检查。这不是类型检查(为此,我们需要使用C ++的typeid),只检查大小。

如果您需要返回值,则认为需要传递另一个变量:

#define OSAtomicCompareAndSwap(ret, old, new, mem)  do{ \
     if (sizeof(*old) == sizeof(int32_t)) { \
        ret = OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem));  \
     } else if (sizeof(*old) == sizeof(int64_t)) { \
        ret = OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem));  \
     } else assert(0); }while(0)

或ex。将指针传递给要与结果等一起存储的变量。或者,您可以使用statement expression gcc扩展名。

带有如下语句的表达式:

#define OSAtomicCompareAndSwap(old, new, mem)  __extension__({ \
     int64_t ret = 0; \
     if (sizeof(*old) == sizeof(int32_t)) { \
        ret = OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem));  \
     } else if (sizeof(*old) == sizeof(int64_t)) { \
        ret = OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem));  \
     } else { \
          assert(0); \
     } \
     ret; \
})