Search code examples
c++math.hconst-correctness

Why const correctness rule doesn't work for built in libraries?


There is a rule about const methods. If the method is const, and we are trying to use another function at the same method, so it should be const as well. Otherwise, we will have a compilation error. I was trying to find the declaration of abs() function in math.h library, and here is what I found: Declarations of abs() It means that the abs() function is not const, but when I use it inside const method I am not having a compilation error. can somebody explain why is that?

class D:public B,C
{
public:
    D()
    {
        cout<<"This is constuctor D"<<endl;
    }

    int fun3() const;

    ~D()
    {
         cout<< "Destructor D"<<endl;
    }
};

int D::fun3() const
{
    int x=-3;

    return abs(x);
}

Solution

  • To start, unlearn what you think you know. Let's look at what it means to be a const member.

    class D {
    public:
        int fun2();
        int fun3() const;
    };
    

    What does this declare? There is a class called D. There are two member functions fun2 and fun3, each taking a hidden this parameter and no other parameters.

    Hold on! A hidden parameter? Well, yes. You can use this within the function; its value has to come from somewhere. All non-static member functions have this hidden parameter. However, not all non-static member functions have the same type of hidden parameter. If I were to show the hidden parameter, the declarations would look like the following:

    int D::fun2(D * this);
    int D::fun3(const D * this);
    

    Notice how the const exists inside this pseudo-declaration? That is the effect of declaring a const member function: this points to a const object rather than a non-const object.

    Now back to the question. Can fun3 call fun2? Well, fun3 would pass its this pointer (a pointer-to-const-object) to fun2, which expects a pointer-to-object. That would mean losing constness, so it's not allowed.

    Can fun3 call abs? Well, fun3 would pass an integer to abs. No problem here. The problem is losing the constness of this. As long as you avoid that, you're fine.