Is there any advantage in declaring a variable local to a function const? i.e., I want to use a sine value a couple of times so I store it in a local variable. If I make it const does this facilitate any compiler optimizations... or anything beneficial?

double my_func(double pitch, ...) 
{
  const double sP   = sin(pitch * 0.5);

  ...

}

Recommended Answers

All 17 Replies

I'm being lazy so I'll just quote page 337 of "Thinking in C++":

"As a matter of practice, if you think a value shouldn't change, you should make it a const. This not only provides insurance against inadvertent changes, it also allows the compiler to generate more efficient code by eliminating storage and memory reads."

Basically the compiler tries to avoid allocating storage for const where possible, which in turn creates more efficient code.

When you declare a variable to be a constant, it causes the compiler to spit out an error if the code ever tries to change it. Basically, it is another tool to prevent errors.

Perhaps you are thinking of static variables?
A static variable retains its value between function calls. A static local variable is known only within the function in which it is defined, like all local variables. However, the benefit is that in the case of computationally expensive calculations (like a sinudoidal function, which is an infinite series) it only gets computed once. If you are certain the variable does not change later in the program, you could avoid re-computing the same quantity every time the function is called.

Thanks for the quick responses.

In this case the value may differ every time the function is called so I can't make the variable static.

I recognize the benefit of using const wherever possible to catch mistakes and improve readability.

What I'm really wondering is whether giving the const qualifier really does facilitate any compiler optimizations (in the case of a variable which is local to a function and only assigned upon initialization).

-I'm wondering if hunting down and clarifying all these cases in a moderately large software project will yield any tangible benefit (besides stylistic improvement).

If the value of pitch is not known at compile time then storage is required and the code will not be more efficient. The only benefit you will get is that of the added safety of not being able to accidentally change the variable during run time.

Thanks for the quick responses.

What I'm really wondering is whether giving the const qualifier really does facilitate any compiler optimizations (in the case of a variable which is local to a function and only assigned upon initialization).

Read Necrolin's post.

-I'm wondering if hunting down and clarifying all these cases in a moderately large software project will yield any tangible benefit (besides stylistic improvement).

No. If you are trying to optimize a program, look elsewhere. You might save a couple nanoseconds, but that's about it. I would not bother with such changes unless there is something else to change too.

Thanks for the answers.

Incidentally, Ancient Dragon, your comment that I might save a few nanoseconds is confusing. It seems to imply that some computation time might be saved. Either there is absolutely no computational efficiency benefit possible, or I could potentially save an indeterminate amount of actual computation time depending on the frequency of calls to such a function.

I'm not meaning to be pedantic, but rather assure myself that there really is no possible efficiency benefit...?

Whether or not there is computational time will be compiler dependent. Assuming you have a good optimizing compiler and do NOT compile the program for debug, the compiler will may or may not toss out any storage for constants and keep the value in registers. That, however, is pretty unlikely with Intel (or compatible) processors due to limited number of registers. So most likely some CPU time will be spent loading a register with the storage location of the const variable before it can be used for anything. So whether that variable is an int or a const int makes no difference because it still will have to be store some place.

The same program compiled on a machine with a different CPU type may handle const completely differently.

So the short answer to your question is -- maybe yes and maybe no

Whether or not there is computational time will be compiler dependent. Assuming you have a good optimizing compiler and do NOT compile the program for debug, the compiler will may or may not toss out any storage for constants and keep the value in registers. That, however, is pretty unlikely with Intel (or compatible) processors due to limited number of registers. So most likely some CPU time will be spent loading a register with the storage location of the const variable before it can be used for anything. So whether that variable is an int or a const int makes no difference because it still will have to be store some place.

The same program compiled on a machine with a different CPU type may handle const completely differently.

So the short answer to your question is -- maybe yes and maybe no

You know, I suspect that many billionaires are ecstatically happy.

You know, I suspect that many billionaires are ecstatically happy.

I'm a little sloooow and don't get the connection :confused:

[edit]Ohhhh! I get it now. You were talking about my signature :) [/edit]

Thanks for the answers.
your comment that I might save a few nanoseconds is confusing. It seems to imply that some computation time might be saved.

You still have to type const just typing this once at about 0.4 seconds = 400, 000, 000 ns.

You rely on the compiler to write the machine code and using a high level language you should not expect a difference between the handling of a const int and an int, even if on some compilers you get a difference. The computer still can overwrite an area of RAM even if you declare it const.

Just as in theory:

const double sf(sin(pitch/2));

should be faster you should expect the compiler to give the same machine code and if you try to compensate for compiler short-falls eventually the compiler will be replaced and your code risks becoming slower overnight and you shorten the reusability life of your code.

Const is useful to keep your code readable and hence reusable - for a short scoped function there is very little benefit, and often refactoring your code means that you have to pass the variable across several methods and are better off with a class and member variable.

Its benefit is really in telling someone else who looks at your source code that your intention is for this value not to change.

similarly a return value of a function is an overhead and you cannot pass a constant variable as a reference to be changed/initialised by a function.

Whether or not there is computational time will be compiler dependent. Assuming you have a good optimizing compiler and do NOT compile the program for debug, the compiler will may or may not toss out any storage for constants and keep the value in registers. That, however, is pretty unlikely with Intel (or compatible) processors due to limited number of registers. So most likely some CPU time will be spent loading a register with the storage location of the const variable before it can be used for anything. So whether that variable is an int or a const int makes no difference because it still will have to be store some place.

I thought there was the thing in C++ where constant variables were generally optimized away and treated as #defines.

#include <iostream>
using namespace std;

int main()
{
   const int x = 10;
   int *y = const_cast<int*>(&x);
   cout << "x = " << x << ", *y = " << *y << "\n";
   *y *= 2;
   cout << "x = " << x << ", *y = " << *y << "\n";
   return 0;
}
/* my output
x = 10, *y = 10
x = 10, *y = 20
*/

I thought there was the thing in C++ where constant variables were generally optimized away and treated as #defines.

You're right and they are expanded in place where possible. But for this to be possible you must know what the value will be at compile time, you cannot implicitly or explicitly pass the address of the constant, it has to be simple enough to work with the compiler's symbol table, etc.

However, Ancient Dragon and Tetron gave reasons for why the code may not in fact be faster. So, the final answer is still "it depends."

I thought there was the thing in C++ where constant variables were generally optimized away and treated as #defines.

Fantastic. I mean, wow. Phantastic in fact. I wouldn't believe it unless I compiled and run it myself.
The assembly output does show indeed that constant variable x is replaced by a literal. An immediate question arises, what is its address (or a reference to it). It turns out that an anonymous variable - initialized with an original x value - is created, and its address is taken.
A real question is, does the Standard mandate such behaviour?

This looks like undefined behaviour

7.1.6.1

Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior. Example:

<snip>

const int * ciq = new const int(3); // initialized as required
int * iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined, modifies a const object

commented: Right, thank you. +1

This looks like undefined behaviour

Undefined indeed.

I understand that the bit of code I posted containing the attempted modification of a const object is UB. If anyone can come up with a better example to illustrate this same matter with constants, or find me a reference page on this (I've tried, I was sure cdiffs would have it), or in any way clarify what I was taking about (rather than what I wasn't talking about), I'd greatly appreciate it.

What I was trying to get at was:

I thought there was the thing in C++ where constant variables were generally optimized away and treated as #defines.

I suppose there would be this attempt:

#include <iostream>
using namespace std;

int main()
{
   const int x = 10;
   cout << "x = " << x << "\n";
   return 0;
}

...leaving it to the individual to look at the underlying generated assembly to see whether or not an 'x' is loaded with a value and later its this value then is read, or if the value 10 is directly substituted.

But what I really am asking is:

I thought there was the thing in C++ where constant variables were generally optimized away and treated as #defines.

What is this thingy that I'm trying to name or whatever?

> What is this thingy that I'm trying to name or whatever?
Well, it is part of the IS, under section 7.1.5.1 'The cv-qualifiers'

A variable of const-qualified integral or enumeration type initialized by an integral constant expression can be used in integral constant expressions - IS 7.1.5.1/2

A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it is treated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path. [Note: cv-qualifiers are supported by the type system so that they cannot be subverted without casting] - IS 7.1.5.1/3

Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior. - 7.1.5.1/4

Compilers do implement the optimization allowed by this; for example:

int foobar()
{
    const int c1 = 100 ;
    const int c2 = 25 ;
    const int* p1 = &c1 ;
    const int* p2 = &c2 ;

    return *p1 - *p2 ; // generates code for return 75 ;
}

> g++ -Wall -std=c++98 -O3 -fomit-frame-pointer -S -c foobar.cc
> cat foobar.s

.file "foobar.cc"
.text
.p2align 4,,15
.globl __Z6foobarv
.def __Z6foobarv; .scl 2; .type 32; .endef
__Z6foobarv:
LFB2:
movl $75, %eax
ret
LFE2:

commented: Danke. +13
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.