Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the definition of const-correctness?

Tags:

c++

constants

I thought the concept of "const-correctness" was pretty well defined, but when I talked to other people about it, it seemed we had different ideas of what it means. Some people say it's about a program having the "const" annotations in as many places as possible. Others define a program as const-correct if and only if there are no violations of constness where the const annotation is used (ie. it's a property that the compiler checks for you).

So I'd like to know, which of these functions are const correct:

struct Person {
    string getName1() const { return _name; }
    string getName2() { return _name; }
    string getName3() const { _name = "John"; return _name; }
    string getName4() { _name = "John"; return _name; }

    string _name;
};

I've searched on the Internet for definitions but couldn't really find definite answer, and I also have suspicions that there might be a case of citogenesis at play. So could anyone provide any solid citation for a definition?

like image 908
exclipy Avatar asked Nov 26 '11 10:11

exclipy


2 Answers

In my view "const correctness" means:

Everything that isn't intended to be modified should be marked as const.

This means that the compiler can tell you when you make a mistake. (It also possibly has implications for optimisations in certain conditions, but that's more of a secondary benefit and depends on a lot of other factors)

There are three basic places where this is useful:

  1. Member functions can be marked const, as in your examples. This means that your accesses to member variables from within that function will be as though the variables themselves were const. (This is the example you've shown, although getName3() won't work)

  2. "Free" variables, local and member variables themselves may also be marked const - once initialised they may not be changed. Example - local variable:

    int f(int i) {
       const int square = i*i;
       // do something here that uses, but doesn't change square
       return square;
    }
    

    Or free variable:

    extern const double PI; // set somewhere else but not changed.
    

    Or member variable:

    class foo {
       const int state; // can't be changed once constructed
       foo(int s) : state(i) {}
    };
    
  3. Function arguments can also be marked const, the definition can match a non-const declaration still:

    void f(int i);
    void f(const int i) {
        // the fact that i is const is an implementation detail of f here
    }
    

    As a side note const correctness for references is required in some cases:

    void g(const std::string& s);
    void f(std::string& s);
    

    Of these two one can be used in more places:

    g("hi"); // Fine
    f("hi"); // Not fine - you can't bind a temporary to a reference
    

    Of course if you meant to change s then passing a temporary in makes little sense anyway.

like image 187
Flexo Avatar answered Sep 30 '22 19:09

Flexo


Text from parashift:

It means using the keyword const to prevent const objects from getting mutated.

like image 20
KV Prajapati Avatar answered Sep 30 '22 20:09

KV Prajapati