2011-05-02

Unexpected behavior: pointer to constant

Preface: some words about correct 'const' syntax

The general rule is that the const keyword affects its immediate left neighbor. Sic! So the correct syntax for defining a pointer to a constant integer is int const * pInteger. The history proved that the traditional style is not sufficient, but is still maintained: If the const keyword is the leftmost in a type specification then it affects its immediate right neighbor.

Constants are to be disposed too

#include <iostream>
class A {
public:
        A(){ std::cout << "Risen #" << (idx=++counter) << std::endl; }
        ~A(){ std::cout << "Fallen #" << idx << std::endl; }
private:
        int idx;
        static int counter;
};
int A::counter = 0;

int main(){
        A const first;
        return 0;
}

will output (as expected)

Risen #1
Fallen #1

As we can observe, the destructor of the const-qualified first variable was called. That extrapolates that the const qualifier does not protect from calling the destructor on a pointer which is a weird looking thing for the first time.

The unexpected behavior

#include <iostream>
class A { /* same as the above */ };
int A::counter = 0;
void f(A const * pTest){ delete pTest; }

int main(){
        A *pFirst = new A, second;
        f(pFirst);
        A const third;
        return 0;
}

will compile flawlessly and will produce

Risen #1
Risen #2
Fallen #1
Risen #3
Fallen #3
Fallen #2

The bad idea

Let's make it impossible to call a delete on pointers to constants! Bad idea. The following example must be possible.

Vector2D const * pVector = new Vector2D(3,2);
// ...
delete pVector; // <--- This is it.

And the deletion of a pointed value must be delegable to functions. That's why the f() was able to delete its parameter.

One may feel unsafe at this moment, but it is not really a problem in the industry: almost nobody has the clue that it is even possible, and nobody wants to do that anyways, except when it is the main goal. But then it's not a trap.

No comments:

Post a Comment