views:

272

answers:

3

I have a piece of code with the following rough signature:

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

Most compilers will happily swallow the assignment of pArray, but chokes on the assignments of nElements. This inconsistency confuses me, and I would like to be enlightened.

I have no problem accepting that you can't assign a const integer, but then why does it works as I expect for the const-pointer-to-const?

The fast and cheap fix is to drop the const qualifier, but that might introduce subtle bugs since much of the code inside the loop is macrofied (I've been bitten by that once). How would you restructure the above to allow a constant element counter?

A: 

I have no idea what's up with pArray, but for nElements you can just use a ternary instead of if-else:

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

If you don't like ternaries, declare a little function that computes nElements, and use that to initialize.

Jacob B
+5  A: 

In your declaration of pArray

const int const * pArray;

Both 'const' keywords actually apply to int. To get one to apply to the pointer, you'd have to declare it as int const * const pArray, in which the pointer itself becomes immutable. Your compiler should then throw an error on both assignments.

Michiel Buddingh'
I'll accept this since it's the most succinct answer.
Christoffer
+6  A: 

As Michiel pointed out, your declaration:

const int const * pArray;

isn't quite correct.

You have four (4) syntatic choices:

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