Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a const-correct (C++) library that relies on a non-const-correct library

I'm building a library in C++ (mostly for fun) that I've been working on for a while now (years, haha, it's just a hobby)

I recently switched some of the underpinnings (read, library dependency) to another library. Unfortunately, said library is not concerned at all with 'const-correctness'. I'm a bit OCD and I like to challenge myself to do things "The Right Way™", so I'd like to make my library const-correct. I've started this a few times, and some parts are; I know that it's better to start const-correct from the beginning but that's not really relevant or up for debate. The fact is that I'm interested in giving it an earnest go again, but the other library prevents me from doing so.

Hows that, you might ask?

Well if I'm calling a method that clearly should be const (doesn't actually change anything), and my method is also a candidate for const-ing (new word), I cannot ensure const-ness on my method until that other method is also const.

Example:

// Bad third-party library

struct Foo
{
    void should_be_const() {}
};

// My library

struct Bar
{
    Foo my_foo;
    void should_be_const() const
    {
        my_foo.should_be_const(); // ERROR!  Not a const function!
    }
};

This is only apparent to me from empirical evidence and from my research and understanding about const-ness. However, this could be a falsely formed understanding so I'm open (and hopeful?) to it being wrong and shown otherwise (although that would shake the foundation of my understanding of const-ness haha)

What's a poor soul to do if he (or she) wants to write a proper library but a dependency isn't written that way?

I hope this is an appropriate question for SO. Please (I'm sure you will) let me know if it's not or if there is a better StackExchange site to post it on.

P.S. I've found this SO question, but I was hoping the topic/solution could be elaborated on.

like image 542
Volte Avatar asked Jun 13 '14 21:06

Volte


1 Answers

The other question you referenced gives a pretty good lead on what the issues are but I'm going to disagree a bit with the answer. The interfaces in your sub-libraries are going to break into four cases.

  1. Things that are not const and cannot be expect to be.
  2. Things properly declared const
  3. Things that logically should be const, and

    3a. Are implemented as such but are not declared so

    3b. Are not implemented as such

Case 1 is easy - if you want yours to be const, then you need to make a copy of the input before calling that interface. A cast would be just wrong and will eventually lead to a crash or other error. Case 2 is not an issues. So cases 3 it is.

Unfortunately, the reality is that cases 3a and 3b should be treated identically to case 1 because they are indistinguishable. The implementation could change by platform or version. So, you should create a copy and then call the interface. Notice I said "should." The reality is that most of us will use a const_cast for calling interfaces we think we understand (e.g. strcmp). It becomes a judgment call about how confident we are in the implementation. Personally, I wouldn't worry about strcmp. Pretty much anything higher level could use something like strtok which will break things.

like image 102
DrC Avatar answered Oct 07 '22 22:10

DrC