C++ const

This topic is 2504 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi all,

I was recently told (by a person of authority) not to use const qualifiers on anything that's not a reference or pointer. E.g.:

void SetX(const int _x);

In fact, I was pretty much told I was stupid for doing this when I asked why not. I'm not exactly what one would consider a noob to c++ since I've been using it professionally for about 5 years now, but I do learn new things every now and then. My understanding is that const is only used by the compiler (in this case g++) to flag for user errors and has no impact on the executable generated?

I've looked around but couldn't find anything one way or another. The only thing I can think of is saving 6 bytes on the git download. Anyone have anything better?

Share on other sites
Well, the const in this case doesn't make sense. It means you are not allowed to modify the variable inside the function, but since it is a copy anyways, that restriction is unnecessary.

Share on other sites
Whether a parameter in a prototype is const or not makes no difference whatsoever. Not to the compiler, not to someone trying to use your function or reading your code. So having it there only makes things less clear, since it's not customary and it might lead someone to believe it means something.

The way I program, most of my local variables are initialized when they are defined and their values never change, so I could make them all const', and the compiler would tell me if I am accidentally changing one. But this is very rarely a mistake I make, and the overabundance of const's would clutter the code and make it harder to read, so I don't do it.

If I were designing the language, perhaps I would make the default be const' and you would have to use the keyword variable' when you need the value to change.

Share on other sites
I just talked to some people who used to work with this guy and you are both right, and so am I. I'd always just done that as a matter of formality; didn't matter if the value could be changed or not in a function call. It turns out the person who made this comment to me 1) thinks it makes the code less-readable/open-to-interpretation and 2) wastes 6 bytes (or 12) on code checkouts.

I suppose both are valid in some degree. Like I said, learn something new every day ...

Share on other sites
It serves a different purpose than making a reference or pointer parameter const. Making a reference or pointer parameter const is a promise to the caller that you will not modify what they refer or point to.

Making a parameter of a built-in type const simply forces the internals of the function to not modify the value that is entirely internal to the function. Generally most people don't need this because they will just be calling your function, not modifying it.

Also, when it comes to return types, you certainly don't want to make the return value const. Doing that has absollutely zero effect, but causes some compilers to generate warnings. A.k.a it is bad.

Share on other sites
Everything has really been said in this thread in one way or another, but just to clarify:

In function declarations, adding const to a pass-by-vaue function parameter is as good as whitespace. It will be ignored by the compiler. However, in function definitions, the const works as expected and ensures you don't modify that value in the body of the function. Many books, such as C++ Coding Standards, recommend not adding const to pass-by-value types in the declaration to avoid confusion. However, definitions are another story and since the const is effectively ignored, these signatures match and is legal:

void Foo(int x); void Foo(const int x) { // ... }

The second thing that was brought up was returning by const value. Returning by const value is pointless for built-in types. However, user-defined types should be returned by const value because it prevents you from calling non-const member functions on rvalues (temporaries). For example:

Vector operator+(const Vector& a, const Vector& b); const Vector operator-(const Vector& a, const Vector& b); Vector a, b, c; a + b = c; // This compiles, but you're assigning to a temporary, and is likely a bug better caught at compile-time a - b = c; // This does not compile, because operator= is (or should be) a non-const method

Share on other sites
As far as I know (but glad to be corrected), const may also have benefical effects on performances: it tells the compiler that the variable (which may be temporary) will not be changed, so it can optimize code to skip copies.

Share on other sites

As far as I know (but glad to be corrected), const may also have benefical effects on performances: it tells the compiler that the variable (which may be temporary) will not be changed, so it can optimize code to skip copies.

This generally isn't true thanks to const_cast, which can remove the const qualifier. C++11 added the constexpr keyword, which does guarantee the value is locked at compile time.

That said, I personally tend to go the overkill route and declare everything const, unless I know I'm going to need the change the value.

Share on other sites

As far as I know (but glad to be corrected), const may also have benefical effects on performances: it tells the compiler that the variable (which may be temporary) will not be changed, so it can optimize code to skip copies.
[/quote]
Most of the time, the compiler can determine whether it can skip a copy regardless of whether the object is const or not. In the cases it can't, it generally won't help declaring it const, the C++ aliasing problem being something that might cause such an optimisation to be rejected.

Const is almost never a performance optimisation.

Share on other sites
C++11 added the constexpr keyword, which does guarantee the value is locked at compile time.
That is not quite true either. [font=courier new,courier,monospace]constexpr [/font]only guarantees that a value can be used as a compile-time constant. If you assign a constexpr to anything other than a template parameter or an [font=courier new,courier,monospace]enum [/font]value (or use it in an array declaration), it will be a plain normal value like every other. It might of course still be optimized out, but does not generally happen, as a guarantee. Try it, you'll be surprised.

On the other hand, [font=courier new,courier,monospace]constexpr [/font]comes with some non-obvious limitations (such as restrictions of what can go into a [font=courier new,courier,monospace]constexpr[/font]), gotchas and compiler-particular issues (for example gcc considers [font=courier new,courier,monospace]__func__[/font] or [font=courier new,courier,monospace]typeid.name()[/font] as something that can not be passed to a [font=courier new,courier,monospace]constexpr[/font], although they very obviously are compile-time constants).

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
14
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• Forum Statistics

• Total Topics
633662
• Total Posts
3013231
×