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