What does const& mean?

Basically, what does it mean to have for example this:

1
2
3
4
void somefunction(const int &value)
{
  //code here
}


I know what const is and I know what the reference symbol is, but what do I gain by using them like that?
Last edited on
With an int you really don't gain much over passing the variable by value. But when using more complex data types it eliminates the possibly costly copy operation while insuring the function doesn't modify the parameter.

The const in that case means that value is, for all intents and purposes, read only. You can only use the value, you can't change it.

1
2
3
4
5
void somefunction(const int &value)
{
    int x = value; // Valid
    value = 0; // Invalid
}
Would big classes count as more complex data types? So am I understanding correctly that const& is only used to pass a value with a pointer? So would something like this be identical?

1
2
3
4
5
6
void somefunction(int *value)
{
  //code
}
int i = 10;
somefunction (&i);
No, that wouldn't be identical exactly. The const just prevents you from modifying the data being pointed at.

This would be identical:
1
2
3
4
void somefunction(const int* value)
{
    // code
}


What jlb was getting at is that as far the amount of data passed, an int offers no difference since an int is generally 4 bytes in size, and a pointer is also generally 4 bytes in size, meaning you're passing 4 bytes of data regardless.

However if your class is, say, 256 bytes in size, a pointer to that class is still only 4 bytes and passing it by pointer/reference has real value as you're passing 252 fewer bytes of data.
Last edited on
Pointers and references are different things. A reference is a synonym for another piece of data. It is usually implemented with a pointer, but they aren't the same thing. In particular, you can't change what a reference refers.

Would big classes count as more complex data types?
Yes, exactly.
So would something like this be identical?
No. In your example, you can change value to point to something else, and you can change the value that it points to. With a reference you can't change what it refers to. With a const reference you can't change what it refers to, or the referenced value.
Huh, and all this time I've been under the impression that C++ references were more basic than that. I stand corrected. Thanks. :)
Last edited on
Closest in meaning:

const int &value;

const int * const pvalue;
That's what I figured, but decided to go read about references just in case. I know a const pointer can be forcibly reassigned through a cast but I had no idea a reference stands above even that. Serves me right for never really giving them a good look, I guess. *Ashamed*
I know a const pointer can be forcibly reassigned through a cast
It only seems to work (so it compiles and maybe even produces expected results), but changing constant variable is Undefined Behavior and anything can happens.
The only way I can think of where "anything" could possibly happen from such an action would be if the compiler generates arbitrarily different assembly code, which I think would be odd. But I guess there could be things regarding optimization that could screw with it.

The way I understand it a pointer is just a pointer and the CPU has no concept of const. Anywhere I might be able to look to understand -why- such behavior is undefined?
Last edited on
Assigning to a const variable might mess up optimization. In addition, the compiler might put a const variable in read-only memory, so an attempt to write to it could crash the program.

But really MiiniPaa is right in saying that the behavior is undefined. That means that any behavior is "correct".
The only way I can think of where "anything" could possibly happen from such an action would be if the compiler generates arbitrarily different assembly code
That's unlikely to happen. I think a better way to think about undefined behavior is to recognize that any behavior is "correct" behavior. Put another way, you can't complain about what happens when the behavior is undefined.

The way I understand it a pointer is just a pointer and the CPU has no concept of const
Not necessarily. Const data could be put into memory that the hardware marks as read-only. If you tried to write to it, you'd get an interrupt that would probably result in the program crashing.

I guess there could be things regarding optimization that could screw with it.
Exactly. The optimizer may take advantage of the knowledge that the data won't be changed. If you do, in fact, change it, then the optimization might break.
Mandatory links:
http://blogs.msdn.com/b/oldnewthing/archive/2014/06/27/10537746.aspx
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

The optimizer may take advantage of the knowledge that the data won't be changed. If you do, in fact, change it, then the optimization might break.
It is actually worse. Modern compilers often assume that programmers are competent and will never let UB happen. So if you have several code path some of which can result in UB, compiler can assume that it will never happen:
1
2
3
4
5
6
7
8
9
void foo(bar* x)
{
    //We are dereferencing pointer 
    //Would lead to UB if it is null
    std::cout << x->something; 

    if(x == nullptr) //As we dereferenced it before, compiler allowed to assume that it will never be null
        do_something(); //This might be never executed
}

Another UB examples:
1
2
3
4
5
6
7
8
9
//Can cause infinite loop
//Signed integer overflow
#include <iostream>

int main()
{
    for (int i = 0; i < 4; ++i)
        std::cout << i*1000000000 << std::endl;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Schrödinger variable
//Using uninitialized variable
#include <iostream>
using namespace std;

void foo()
{
    int i = 0xffffffff;
    cout << i << endl;
}

void bar()
{
    bool b;
    if(b)
        cout << "true" << endl;
    if(!b)
        cout << "false" << endl;
}

int main()
{
    foo();
    bar();
}
-1
true
false
http://coliru.stacked-crooked.com/a/ac073b2238f84e0b

Last edited on
Topic archived. No new replies allowed.