2010-11-29 5 views
0

au moment où je suis occupé de jongler avec les opérations CAS et verrouillage/algorithmes d'attente sans, et pour ma propre santé mentale j'ai décidé de mettre en œuvre un modèle de manipulation tout le casting pour moi:Essayer de créer des modèles 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))); 
} 

Cependant, en utilisant un code de test simple, je ne peux pas obtenir ce travail sur une destination volatile, qui est nécessaire pour pr réorganisation d'événement.

Test Code:

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

Sous VC6 je reçois cette erreur:

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

et GCC recrache ceci:

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

est-il possible d'obtenir un modèle pour CAS ops qui ne casse pas lorsque la destination est volatile ou suis-je coincé avec une macro?

+0

'static_assert'? Utilisez-vous C++ 0x? – kennytm

+0

@KennyTM: pour la construction de GCC, oui, sous VC j'ai une macro à mapper vers un index de tableau invalide. il n'est pas étiqueté C++ 0x car j'essaie d'éviter les constructions C++ 0x à l'exception de celles qui sont émulables avec des macros. – Necrolis

+0

'InterlockedCompareExchange' ou' InterlockedCompareExchangePointer'. vous ne devriez pas les mélanger. –

Répondre

1

OK si j'appelle la fonction CAS comme suit:

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

Puis-je obtenir une autre erreur:

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

Cela donne plus d'un indice quant à ce qui se passe mal.

Une façon de le résoudre serait d'introduire un typedef comme suit:

typedef int* pint_t; 

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

techniquement,' NULL' devrait être '(void *) 0', mais lancer' NULL' à 'int * 'ne fait aucune différence, GCC crache toujours:' error: aucune fonction correspondante pour l'appel à 'CAS (volatile int **, int *, int * &)' ' – Necrolis

+0

Ouais juste vérifié que moi-même ... – Goz

+0

@Necrolis: Re-a écrit ma réponse :) – Goz

Questions connexes