0

現時点では、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)));
}

GCC 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 *'

そしてGCCはこれを吐き出します:

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

volatile宛先がマクロである場合、またはマクロでスタックしている場合に壊れないCAS opsのテンプレートを取得することは可能ですか?

4

1 に答える 1

1

次のようにCAS関数を呼び出すとOKです。

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

次に、別のエラーが発生します。

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

これにより、何がうまくいかないかについての手がかりが得られます。

これを解決する1つの方法は、次のようにtypedefを導入することです。

    typedef int* pint_t;

volatile pint_t p;
int i = 2;
pint_t pi = &i;
CAS<pint_t>( &p, NULL, pi );
于 2010-11-29T08:51:35.513 に答える