2009-06-10 5 views
1

J'ai un morceau de code avec la signature approximative suivante:Pourquoi ne puis-je pas attribuer une valeur const et que faire à la place?

void evaluate(object * this) 
{ 
    static const int briefList[] = { CONSTANT_A, CONSTANT_Z }; 
    static const int fullList[] = { CONSTANT_A, CONSTANT_B, ..., CONSTANT_Z}; 

    const int const * pArray; 
    const int nElements; 
    int i; 

    if (this->needDeepsEvaluation) 
    { 
     pArray = fullList; 
     nElements = sizeof(fullList)/sizeof(fullList[0]); 
    } 
    else 
    { 
     pArray = briefList; 
     nElements = sizeof(briefList)/sizeof(briefList[0]); 
    } 

    for (i = nElements; i; i--) 
    { 
     /* A thousand lines of optimized code */ 
    } 
    this->needsDeepEvaluation = 0; 
} 

La plupart des compilateurs se fera un plaisir d'avaler la cession de parray, mais selfs sur les missions de Nelements. Cette incohérence me trouble et j'aimerais être éclairée.

Je n'ai aucun problème à accepter que vous ne pouvez pas affecter un entier de const, mais pourquoi cela fonctionne-t-il comme prévu pour le const-pointer-to-const? Le correctif rapide et bon marché consiste à supprimer le qualificateur de const, mais cela pourrait introduire des bugs subtils car une grande partie du code à l'intérieur de la boucle est macrofiée (j'ai été mordu par cette fois). Comment restructureriez-vous ce qui précède pour permettre un compteur d'éléments constants?

Répondre

5

Dans votre déclaration de pArray

const int const * pArray; 

Les deux mots-clés 'const' appliquent réellement int. Pour en appliquer une au pointeur, vous devez le déclarer int const * const pArray, dans lequel le pointeur lui-même devient immuable. Votre compilateur devrait alors lancer une erreur sur les deux affectations.

+0

Je vais accepter cela car il est la réponse la plus succincte. – Christoffer

0

Je ne sais pas ce qui est avec parray, mais pour Nelements vous pouvez simplement utiliser un ternaire au lieu de if-else:

const int nElements = this->needsDeepEvaluation ? sizeof(fullList)/sizeof(fullList[0]) | sizeof(briefList)/sizeof(briefList[0]); 

Si vous ne l'aimez pas ternaires, déclarez une petite fonction qui calcule Nelements , et utilisez cela pour initialiser.

9

Comme Michiel a souligné, votre déclaration:

const int const * pArray; 

est pas tout à fait correct.

Vous avez quatre (4) choix: syntaxiques

int * pArray;  /* The pointer and the dereferenced data are modifiable */ 
int * const pArray; /* The pointer is constant (it should be initialized), 
         the dereferenced data is modifiable */ 
int const * pArray; /* the pointer is modifiable, the dereferenced data 
         is constant */ 
int const * const pArray; /* Everything is constant */ 
Questions connexes