2

When I asked about what is the different between int and const in C++? Someone says like this.

An int can be modified when you need, it is read/write and a const int is read only.(can change dynamically). You can use a const int for something like fixed value, and const int memory usage is less than normal int.

Is that true const int memory usage is less than normal int. in C++?

5
  • 2
    In general, no. It still needs to be stored somewhere. Commented Apr 30, 2017 at 16:56
  • 2
    An optimizer can very well avoid storing the constant in data space and instead hard-code it as an immediate argument if the value is known. But then the constant appears in program space. It might be replicated in several places and the global memory usage actually be larger. Commented Apr 30, 2017 at 17:00
  • 2
    @YvesDaoust : In C++ it does not even need an optimiser to do that; in C++ it is guaranteed. Replicating it will not increase the code size because an immediate instruction argument is cheaper than fetching a value from memory into a register and passing the register argument, or passing an address argument to an instruction. Requires fewer CPU cycles too. Commented Apr 30, 2017 at 17:33
  • 2
    The compiler may choose to store a variable as a register whether it's declared const or not. So it's possible that in both cases no memory is allocated for the int. Commented Apr 30, 2017 at 17:48
  • As I know avr-g++ not used program memory to store a const Commented Apr 30, 2017 at 18:37

4 Answers 4

6

It might or might not be, depending on how it's used. Most compilers are pretty smart about not creating storage for a const object if they don't need it. So, for example:

void f() {
    const int arr_size = 10;
    int arr[arr_size];
    // do something with arr
}

Here, the only use of arr_size is to specify the size of the array. There's no need to create an int object for that; the compiler just creates an array of size 10.

On the other had:

void f(const int* ip) {
    // do something with ip
}

int main() {
    const int n = 100;
    f(&n);
    return 0;
}

Here, the compiler has to create an int object for n, because the code takes the address of n.

Sign up to request clarification or add additional context in comments.

6 Comments

I think it's still allowed to be optimized if f does nothing with it.
Compiler may inline function so it won't need address. Check it out for yourself. Here compiler loads 100 into register only and calls printf() directly.
@zett42 -- I really don't want to go down a rathole seeking bulletproof illustrations. You get the point of that example, don't you?
@GillBates -- f does do something with it. Read the comment! <g>
The disassembly proofs that your statement the compiler has to create an int object for n, because the code takes the address of n. is wrong. Whether or not an "address" is taken is irrelevant to the compiler in this case. If compiler chooses to inline the function call, the adress operator gets optimized away. Compare the disassembly of this example where I removed const and address. The compiler creates the same assembly for the main() function.
|
2

Same amount of memory is used since they both allocate the size of an int. The only reason to use const is of course to define a constant for a certain pin or value that won't change. int can be read and write, const int can just be read. The reason why const int saves space is because the compiler treat is a value that won't change, so it won't make any adjustments that will allow it to modify its value, thus saving memory.

Comments

2

Const is a thing meant to make the variables not assignable. It is something on a high level to prevent violating the intended constraints. You will not notice any effect, unless for actual constants. (Where I would recommend constexpr instead)

Will this influence memory? No, simply adding const doesn't change anything to the int (or any other class).

Will this assist in optimization? No, compilers are smart enough to deduce constness on it's own if you don't have it.

Why use it? To enforce an API, indicate intend ...

3 Comments

Your first two sentences are contradictory.
I tried to express myself a bit better, still unclear?
Well, the first sentence no longer presents const as if it was some kind of memory-control tool, but now it incorrectly restricts const to the prevention of assignments, which holds true only for primitive types (and only if you see other modifying operations such as ++ as "assignment"). When higher-level types are involved, we are dealing with more abstract rules: a variable being const means that only non-const member functions can be invoked on it. C++ even allows you to overload operator= as a const operation, although that would be terrible coding style :)
2

In C++ unless a const variable's address is taken it is treated as a literal constant and inserted into the code as if its value had been entered literally. That is to say:

const int BUFFLEN = 16 ;
char buffer[BUFFLEN] ;

will generate the same code as:

char buffer[16] ;

The const BUFFLEN does not exist in the memory map as a separate object unless its address is explicitly referenced for example:

printf( "%p", &BUFFLEN ) ;

Given that its address is not referenced, the code generated will be smaller than if it existed in a specific address and had to be fetched and loaded into a register each time it were used.

Moreover no non-const int must exist in R/W memory, but if it has a const initialiser, that initialisation value must exist in the code space too. So for example:

int foo = 16 ;

Will consume space in RAM and also store the initialiser value in ROM (in the case of an Arduino) which is copied to the RAM on start-up before main or any global static object constructors.

So yes it is possible indeed likely that a const will consume fewer resources than a non-const. But I would it is kind of a side-effect of the semantics of const rather than its purpose.

2 Comments

unless a const variable's address is taken it is treated as a literal constant -- even if the address is taken, the compiler may optimize the pointer away and still store the variable in a register. See this disassembly. In line 5, the compiler loads the literal 100 into register esi which will later be passed to printf(). Only if you actually print out the address, the compiler really has to allocate storage, as in this disassembly.
@zett42 : Fair point, although I don't think it invalidates the answer in general. I have modified the answer slightly. Note that printing out the address is not necessary to force it to have storage - it only need to be passed as a function argument and for that function not to be in-lined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.