2

I was wondering if there are any advantages to declaring a function const.

I know that it means that the method cannot modify any non-static class members, but is the only purpose for doing this is to prevent someone from re-implementing the function as something that does modify non-static members, or are there performance differences as well? If there are performance differences, is it likely that the compiler would usually do a better job than humans, such as with inline functions?

Just to clarify, I am asking about the difference between the following member functions:

float getWidth() const
{
    return width;
}

float getWidth()
{
    return width;
}
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
Daniel Underwood
  • 2,191
  • 2
  • 22
  • 48

3 Answers3

7

I know that it means that the function cannot modify any non-static class members

No, const doesn't mean that. It means that you must be allowed to call that function on a constant object, which is an important thing. Even if you do not actually modify any nonstatic data members in a non-const member function, you are not allowed to invoke it on a constant object.

struct A
{
   void f()
   {
   }
};

void g(const A& a)
{
    a.f(); // error
}

More technically, const means that this is of type const ClassName* rather than Classname*. The rest of the rules are direct consequences of this definition.

I don't think potential performance differences are very important here.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 1
    `const` *does* allow the compiler certain optimizations, most of which are already enabled by the strict aliasing rule anyway. In particular, if an object is `const`, pointers to that object generally must preserve the qualifier (you're not supposed to cast it away with `const_cast`). This lets the compiler reduce or eliminate loads and/or spills. – Kevin Dec 19 '14 at 20:13
  • Oh that actually makes more sense than the descriptions of constant functions I have seen; I guess that's where my misunderstanding was. So I suppose if you had a `const` object that you tried to call a non-`const` function on, you would get a compiler error? Also, I see in your edit that your code sample has a `const` argument rather than a `const` function. But what you were explaining is for `const` functions, correct? – Daniel Underwood Dec 19 '14 at 20:15
  • 2
    @Kevin: I didn't say there is no or little performance difference (I really do not know if there is). I just said it's not important, since preference for const-correctness has far more serious justifications. – Armen Tsirunyan Dec 19 '14 at 20:17
  • 1
    @Armen: C++'s `const` keyword is substantially more powerful than analogous features in other languages (cf. Java's `final` keyword). Given C++'s performance emphasis, I'm not sure I agree with you there. – Kevin Dec 19 '14 at 20:19
  • @Kevin: Well, why don't you post an answer emphasizing the performance aspect? – Armen Tsirunyan Dec 19 '14 at 20:20
  • 2
    It is a non sense to compare Java `final` and C++ `const` objects... And I agree that the question is not about performance but semantics (What const methods are intended for ?). And the answer is not performance. – Jean-Baptiste Yunès Dec 19 '14 at 20:23
  • "const doesn't mean that" - it does mean that (except for mutable members), in addition to what you go on to say – M.M Dec 19 '14 at 20:23
  • 1
    @danielu13: The function is non-const so as to illustrate the practical necessity of declaring it const. – Armen Tsirunyan Dec 19 '14 at 20:23
  • 1
    @MattMcNabb: When I say "it doesn't mean that", I mean it in a philosophical sense. If we presume the primary definition to be the one I provided, most of the rules, including the purpose of mutable, are easier to internalize. – Armen Tsirunyan Dec 19 '14 at 20:25
6

Declaring a variable as const allows the compiler to perform a number of optimizations. It may be regarded as a strengthening of the strict aliasing rule. If two pointers are of the same type, ordinarily the compiler must assume they can alias. But if one is declared or used as const, the compiler may ignore potential aliasing with respect to those operations. This can reduce unnecessary loads and spills, leading to simpler, faster code.

It's also important to make your code const-correct, so that it will interoperate properly with other code. Depending on the circumstances, casting away the const qualifier may invoke undefined behavior, so if a function is non-const, it will not be generally possible to use the function on a const object. This will cause problems for anyone who happens to have const objects.

Community
  • 1
  • 1
Kevin
  • 28,963
  • 9
  • 62
  • 81
3

function declarations form a binding contract between the function (method) and the caller.

This is extremely important as it allows the compiler to enforce logically correct programs (it will fail to compile if the programmer attempts to break the contract).

This is the primary and only consideration when declaring functions and their argument lists.

the contracts look like this:

struct A {
  // func promises not to alter the internal state of *this
  void A::func() const;

  // func reserves the right to modify the internal state of *this
  void A::func();
};

// func asserts that it reserves the right to modify a
void func(A& a);

// func asserts that it absolutely won't (actually can't) modify a
void func(const A& a);

// func asserts that it will take a copy of a, which it can modify, 
// store or destroy as it sees fit
void func(A a);

Remember that the compiler enforces these contracts (passing a const A to a function that is exptecting an A& will fail to compile).

This has everything to do with enforcing correctness, and nothing to do with performance.

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142