Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should I not use `const` in this simple function?

When learning C++, one of the first functions one gets for learning the concept of a function is something like

int add(int a, int b)
{
    return a+b;
}

Now I was wondering: Should I use the const-keyword here, or rather not, resulting in

int add(const int a, const int b)
{
    return a+b;
}

But would that make sense? Would it speed my program up, do some other important stuff, or just increase confusion?

like image 262
arc_lupus Avatar asked Oct 04 '16 09:10

arc_lupus


2 Answers

From the caller's perspective, both the first and the second form are the same.

Since the integers are passed by value, even if the function modifies a and b, the modified values are copies of the original and won't be visible to the caller.

However, from the function implementer's perspective there's a difference. In fact, in the second form:

int add(const int a, const int b)

you will get a compiler error if you try to modify the values of a and b inside the function's body, as they are marked as const.

Instead, you can change those values if you omit the const.
Again, those modifications will not be visible to the caller.

like image 163
Mr.C64 Avatar answered Sep 22 '22 10:09

Mr.C64


If you are actually struggling with correctness bugs in your codebase where const would have helped, then add const.

That said, there are related issues that you should consider. Top-level qualifiers of function parameters aren't part of the function type, so your function type is still just int(int, int). (The qualifiers only affect the parameter variables in the function definition.) That means that any declaration of the function also ignores qualifiers, so int add(int, int) and int add(const int, int) and int add(int, const int) all declare the same function. So you have to decide on a policy for how you write header files. And now you have three essential positions you can take:

  1. Always qualify in both declaration and definition. The upside is that this perhaps keeps code looking "consistent" (think copy/pasting when creating implementations). The downside is that the qualifiers have nothing to do with the interface, and are not at all enforcible (you can change the definition later!), so at best it's noise, at worst it's wrong.

  2. Qualify in the definition, but not in the other declarations. The upside is that this communicates the interface correctly and you still get const checking in the definition. The downside is that some people might be confused by the discrepancies in spelling. (Just like people may be confused that a static constexpr T foo; class member can be defined with const T C::foo;.)

  3. Don't qualify either. The upside is that it's consistent, clean, easy to remember and minimal. The downside is that you're missing out on correctness checks in your definition.

There's no right answer. If you're the codebase owner or project lead, you should decide based on what the biggest problems in your codebase and team are. (My personal position is to stick with (3) until you have a good reason to change.)

like image 41
Kerrek SB Avatar answered Sep 21 '22 10:09

Kerrek SB