Почему я не могу присвоить константное значение и что мне следует делать вместо этого?

StackOverflow https://stackoverflow.com/questions/975436

  •  13-09-2019
  •  | 
  •  

Вопрос

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

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, но это может привести к тонким ошибкам, поскольку большая часть кода внутри цикла состоит из макросов (однажды меня это укусило).Как бы вы изменили структуру вышеизложенного, чтобы разрешить постоянный счетчик элементов?

Это было полезно?

Решение

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

const int const * pArray;

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

Другие советы

Как отметил Мишель, ваше заявление:

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top