代码之家  ›  专栏  ›  技术社区  ›  Necrolis

正在尝试创建CAS模板

  •  0
  • Necrolis  · 技术社区  · 14 年前

    目前,我正忙于处理CAS操作和无锁/无等待算法,为了保持清醒,我决定实现一个模板来为我处理所有的强制转换:

    VC6:

    template <typename T> static inline T CAS(volatile T* pDest, T pCompare, T pValue)
    {
        //static_assert(sizeof(T) != sizeof(PVOID),"CAS requires PVOID sized operands");
        return reinterpret_cast<T>(InterlockedCompareExchange(reinterpret_cast<PVOID*>(pDest),reinterpret_cast<PVOID>(pValue),reinterpret_cast<PVOID>(pCompare)));
    }
    

    一般合同条款第4.4.1款:

    template <typename T> static inline T CAS(volatile T* pDest, T pCompare, T pValue)
    {
        static_assert(sizeof(T) != sizeof(long),"CAS32 requires long sized operands");
        return reinterpret_cast<T>(InterlockedCompareExchangePointer(reinterpret_cast<volatile long*>(pDest),reinterpret_cast<long>(pValue),reinterpret_cast<long>(pCompare)));
    }
    

    但是,使用一些简单的测试代码,我不能让它在 volatile 目的地,这是防止重新排序所必需的。

    测试代码:

    volatile int* p;
    int i = 2;
    int* pi = &i;
    CAS(&p,NULL,pi);
    

    在VC6下,我得到这个错误:

    error C2782: 'T __cdecl CAS(volatile T *,T,T)' : template parameter 'T' is ambiguous
            could be 'int'
            or       'volatile int *'
    

    海湾合作委员会指出:

    error: no matching function for call to 'CAS(volatile int**, NULL, int*&)'
    

    有没有可能得到当目的地是 不稳定的 或者我被宏卡住了?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Goz    14 年前

    好的,如果我调用cas函数如下:

    CAS<int*>( &p, NULL, pi );
    

    然后我得到一个不同的错误:

    error C2664: 'CAS' : cannot convert parameter 1 from 'volatile int **' to 'int *volatile *'
    

    这给了我们更多的线索来判断出了什么问题。

    解决这个问题的一种方法是引入一个typedef,如下所示:

        typedef int* pint_t;
    
    volatile pint_t p;
    int i = 2;
    pint_t pi = &i;
    CAS<pint_t>( &p, NULL, pi );