2010-11-29 7 views
0

im Moment bin ich beschäftigt das Hantieren mit CAS-Operationen und Lock/wait freien Algorithmen und für meine eigene geistige Gesundheit zu schaffen, entschied ich mich für mich die ganze Casting Umgang mit einer Vorlage zu implementieren:Versuch CAS Vorlage

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))); 
} 

jedoch einigen einfachen Test-Code, kann ich dies auf einem volatile Ziel zu arbeiten, nicht bekommen, die erforderlich ist, pr Nachbestellung von Ereignissen.

Testcode:

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

Unter VC6 bekomme ich diesen Fehler:

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

und GCC spuckt diese:

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

ist es möglich, eine Vorlage für CAS zu erhalten Ops, die nicht bricht, wenn das Ziel volatile ist oder bin ich mit einem Makro fest?

+0

'static_assert'? Verwenden Sie C++ 0x? – kennytm

+0

@KennyTM: für den GCC-Build, ja, unter VC Ich habe ein Makro zu einem ungültigen Array-Index zuordnen. Es ist nicht mit C++ 0x markiert, da ich C++ 0x-Konstrukte vermeiden möchte, außer denen, die mit Makros multipliziert werden können. – Necrolis

+0

'InterlockedCompareExchange' oder' InterlockedCompareExchangePointer'. Du solltest sie nicht mischen. –

Antwort

1

OK, wenn ich rufen Sie die Funktion CAS wie folgt:

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

Dann habe ich einen anderen Fehler:

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

Dies gibt mehr eine Ahnung, was falsch läuft.

Ein Weg, um es zu lösen wäre, eine typedef wie folgt vorstellen:

typedef int* pint_t; 

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

übertragen werden,' NULL' sollte '(void *) 0' sein, aber' NULL' nach 'int * 'macht keinen Unterschied, GCC spuckt immer noch aus:' error: keine passende Funktion für den Aufruf von 'CAS (volatile int **, int *, int * &)' ' – Necrolis

+0

Ja, hab gerade das selbst überprüft ... – Goz

+0

@Necrolis: Re-schrieb meine Antwort :) – Goz