Skip to main content

I'm going to disagree with the other posters and recommend you don't use top-level const on local variables and parameters. (References and pointers to const, i.e. const T&, are different, and you should use them for correctness at all times when it's appropriate.)

The advantages of top-level const are:

  • Makes it clear that the local variables are not meant to be mutated.
  • Gives a compiler error if you accidentally do attempt to mutate them.

The disadvantages are:

  • Visual clutter.

  • Cannot be used on "pseudo-const" variables, i.e. variables that are initialized in some manner more complicated than direct construction, but not modified after, e.g. using getline:

      std::string line; // cannot be const
      std::getline(std::cin, line);
      // line should be const from here on out
    
  • Prevents move-out optimization on function call and return:

      std::string f1();
      std::string f2(std::string s);
      std::string f3() {
        const std::string s = f1(); // s is not meant to be modified
        // but I still want the move optimization here:
        const std::string result = f2(std::move(s)); // this doesn't move
        // and I want the compiler to move out here:
        return result; // this will probably RVO, but if not, the move
                       // constructor will not be used due to the const
      }
    

    }

I have worked on a codebase where local const was used a lot, and I found it not helpful at all, yet it filled the code with subtle pessimizations as above. I personally prefer to adopt a general policy of modifying variables as rarely as possible, and making functions small enough that the usage of a variable is obvious, and even if it is modified, the complexity of the function is low enough to make it a non-issue.

I'm going to disagree with the other posters and recommend you don't use top-level const on local variables and parameters. (References and pointers to const, i.e. const T&, are different, and you should use them for correctness at all times when it's appropriate.)

The advantages of top-level const are:

  • Makes it clear that the local variables are not meant to be mutated.
  • Gives a compiler error if you accidentally do attempt to mutate them.

The disadvantages are:

  • Visual clutter.

  • Cannot be used on "pseudo-const" variables, i.e. variables that are initialized in some manner more complicated than direct construction, but not modified after, e.g. using getline:

      std::string line; // cannot be const
      std::getline(std::cin, line);
      // line should be const from here on out
    
  • Prevents move-out optimization on function call and return:

      std::string f1();
      std::string f2(std::string s);
      std::string f3() {
    const std::string s = f1(); // s is not meant to be modified
    // but I still want the move optimization here:
    const std::string result = f2(std::move(s)); // this doesn't move
    // and I want the compiler to move out here:
    return result; // this will probably RVO, but if not, the move
                   // constructor will not be used due to the const
    

    }

I have worked on a codebase where local const was used a lot, and I found it not helpful at all, yet it filled the code with subtle pessimizations as above. I personally prefer to adopt a general policy of modifying variables as rarely as possible, and making functions small enough that the usage of a variable is obvious, and even if it is modified, the complexity of the function is low enough to make it a non-issue.

I'm going to disagree with the other posters and recommend you don't use top-level const on local variables and parameters. (References and pointers to const, i.e. const T&, are different, and you should use them for correctness at all times when it's appropriate.)

The advantages of top-level const are:

  • Makes it clear that the local variables are not meant to be mutated.
  • Gives a compiler error if you accidentally do attempt to mutate them.

The disadvantages are:

  • Visual clutter.

  • Cannot be used on "pseudo-const" variables, i.e. variables that are initialized in some manner more complicated than direct construction, but not modified after, e.g. using getline:

      std::string line; // cannot be const
      std::getline(std::cin, line);
      // line should be const from here on out
    
  • Prevents move-out optimization on function call and return:

      std::string f1();
      std::string f2(std::string s);
      std::string f3() {
        const std::string s = f1(); // s is not meant to be modified
        // but I still want the move optimization here:
        const std::string result = f2(std::move(s)); // this doesn't move
        // and I want the compiler to move out here:
        return result; // this will probably RVO, but if not, the move
                       // constructor will not be used due to the const
      }
    

I have worked on a codebase where local const was used a lot, and I found it not helpful at all, yet it filled the code with subtle pessimizations as above. I personally prefer to adopt a general policy of modifying variables as rarely as possible, and making functions small enough that the usage of a variable is obvious, and even if it is modified, the complexity of the function is low enough to make it a non-issue.

Source Link
Sebastian Redl
  • 15.6k
  • 8
  • 60
  • 54

I'm going to disagree with the other posters and recommend you don't use top-level const on local variables and parameters. (References and pointers to const, i.e. const T&, are different, and you should use them for correctness at all times when it's appropriate.)

The advantages of top-level const are:

  • Makes it clear that the local variables are not meant to be mutated.
  • Gives a compiler error if you accidentally do attempt to mutate them.

The disadvantages are:

  • Visual clutter.

  • Cannot be used on "pseudo-const" variables, i.e. variables that are initialized in some manner more complicated than direct construction, but not modified after, e.g. using getline:

      std::string line; // cannot be const
      std::getline(std::cin, line);
      // line should be const from here on out
    
  • Prevents move-out optimization on function call and return:

      std::string f1();
      std::string f2(std::string s);
      std::string f3() {
    const std::string s = f1(); // s is not meant to be modified
    // but I still want the move optimization here:
    const std::string result = f2(std::move(s)); // this doesn't move
    // and I want the compiler to move out here:
    return result; // this will probably RVO, but if not, the move
                   // constructor will not be used due to the const
    

    }

I have worked on a codebase where local const was used a lot, and I found it not helpful at all, yet it filled the code with subtle pessimizations as above. I personally prefer to adopt a general policy of modifying variables as rarely as possible, and making functions small enough that the usage of a variable is obvious, and even if it is modified, the complexity of the function is low enough to make it a non-issue.