Почему я не могу присвоить значение const, и что я должен делать вместо этого? - PullRequest
1 голос
/ 10 июня 2009

У меня есть фрагмент кода со следующей грубой подписью:

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

Большинство компиляторов с радостью проглотят назначение pArray, но подавятся назначениями nElements. Это несоответствие смущает меня, и я хотел бы быть просветленным.

У меня нет проблем с принятием того, что вы не можете назначить целое число const, но тогда почему это работает так, как я ожидаю для const-pointer-to-const?

Быстрое и дешевое решение состоит в том, чтобы удалить квалификатор const, но это может привести к незначительным ошибкам, так как большая часть кода в цикле макроизображена (я был укушен этим один раз). Как бы вы реструктурировали вышеперечисленное, чтобы разрешить постоянный счетчик элементов?

Ответы [ 3 ]

9 голосов
/ 10 июня 2009

Как указала Михил, ваша декларация:

const int const * pArray;

не совсем правильно.

У вас есть четыре (4) синтетических варианта:

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 */
5 голосов
/ 10 июня 2009

В вашей декларации pArray

const int const * pArray;

Оба ключевых слова const на самом деле относятся к int. Чтобы заставить его применить к указателю, вы должны объявить его как int const * const pArray, в котором сам указатель становится неизменным Ваш компилятор должен затем выдать ошибку в обоих назначениях.

0 голосов
/ 10 июня 2009

Понятия не имею, что случилось с pArray, но для nElements вы можете просто использовать троичный вместо if-else:

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

Если вам не нравятся троичные, объявите небольшую функцию, которая вычисляет nElements, и используйте ее для инициализации.

...