Domanda

Ho un pezzo di codice con la seguente firma di massima:

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 maggior parte dei compilatori felicemente ingoiare l'assegnazione di Parray, ma soffoca sulle cessioni di Nelements. Questa incoerenza mi confonde, e vorrei essere illuminato.

Non ho alcun problema ad accettare che non è possibile assegnare un intero const, ma allora perché funziona come mi aspetto per il const-puntatore a const?

La correzione veloce ed economico è far cadere il qualificatore const, ma che potrebbe introdurre bug sottili in quanto la maggior parte del codice all'interno del ciclo è macrofied (Sono stato morso da che una volta). Come si ristrutturare il sopra per consentire un contatore elemento costante?

È stato utile?

Soluzione

Nella vostra dichiarazione di pArray

const int const * pArray;

Sia le parole chiave 'const' in realtà si applicano a int. Per ottenere uno da applicare al puntatore, dovreste dichiararlo come int const * const pArray, in cui il puntatore stesso diventa immutabile. Il vostro compilatore dovrebbe poi gettare un errore su entrambe le assegnazioni.

Altri suggerimenti

Come Michiel ha sottolineato, la tua dichiarazione:

const int const * pArray;

Non è del tutto corretto.

Ci sono quattro (4) scelte syntatic:

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 */

Non ho idea di cosa succede con Parray, ma per Nelements si può semplicemente utilizzare un ternario invece di if-else:

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

Se non ti piace ternari, dichiarare una piccola funzione che calcola Nelements, e l'uso che per inizializzare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top