This question already has answers here:
Purpose of returning by const value? [duplicate]
(4 answers)
Closed 6 years ago.
I think I haven't grasped the proper idea behind returning something that is const.
If I'm having a function which returns const value, doesn't it means that I cannot change the value after I returned it?
Why the compiler allows me to cast my const to a non-const variable?
Or it works only with const pointers?
const int foo(int index) {
return ++index;
}
int main(){
int i = foo(1); // why can I do this?
++i;
return 0;
}
You're doing the equivalent of this:
const int a = 42; // a cannot be modified
int b = a; // b is a copy of a...
++b; // and it can be modified
In other words, you are making a copy of a const object, and modifying said copy.
Note that returning a const value has limited, ehm, value. For built-in types it isn't important. For user-defined types, it can prevent modifying a "temporary" object, at the cost of preventing move semantics. Since C++11 it has become advisable to not return const values.
Related
This question already has answers here:
C++ const object's member can be modified
(1 answer)
Why does C++ not have a const constructor?
(5 answers)
C++, Classes, Const, and strange syntax
(8 answers)
Closed 3 months ago.
class T {
public:
int v;
int &vRef;
public:
T() : v(0), vRef(v) {}
};
const T t; // note, it's a const object
t.vRef = 2;
printf("v: %d\n", t.v);
The code presented above compiles OK, and the const object's internal value did change.
Question. Is this Undefined Behavior or not?
Yes. If the object is declared as const, then modifying it (through any means, be that a non-const reference like in your example, via const_cast or something else) is UB.
This question already has answers here:
Does a const reference class member prolong the life of a temporary?
(6 answers)
Closed 3 years ago.
I'm reviewing code and which looks kind of wrong to me.
I know it can be written in another way and I know it is probably useless to write it this way.
Still, I was surprised that the compiler didn't generate any error/warning so I wonder if it is legal and why.
struct A
{
int val = 0;
int* GetVal() {
return &val;
}
};
void main()
{
A a;
int* const& r = a.GetVal();
}
AFAIK, a reference represents a real variable. The reference and the variable should both have the same memory address.
In this example, there is no variable holding the address (maybe a temporary?) so which variable does r refer to?
If I remove the const it doesn't compile.
There's one special case with references: a const reference is allowed to be bound to a temporary object, and it extends the lifetime of that temporary. Non-const references can't do this magic.
In your code, GetVal() returns a pointer by value, that is it returns a temporary pointer object. When used as a const reference initializer, the compiler stores that pointer value somewhere (most likely in the current stack frame) and binds the reference to that location.
This question already has answers here:
Does a const reference class member prolong the life of a temporary?
(6 answers)
Closed 5 years ago.
Am I right, that this (taken from this GotW):
string f() { return "abc"; }
void g() {
const string& s = f();
cout << s << endl; // can we still use the "temporary" object?
}
is completely fine, while this is not ok at all:
const string& foo() { string x{"abc"}; return x; }
void bar() {
const string& y = foo();
}
?
Why is it different? Can one say that "the lifetime of a temporay is not extended across a function call (even if bound to a const ref)" ?
Or what is an explanation, why the first is ok, but not the second?
The 1st one is pretty fine, because the returned value (which is a temporary) is bound to a reference to const directly, then the lifetime of the temporary is extended to the reference's lifetime.
Note that there's no temporary in the 2nd case, x is a local variable which will be destroyed when get out of the function, then the function will always returns a dangled reference; that reference is used to initialize y but nothing changes, y will be a dangled reference too.
This question already has answers here:
non-class rvalues always have cv-unqualified types
(2 answers)
Should I return const objects?
(12 answers)
What this const before method name mean?
(1 answer)
Closed 8 years ago.
I've tried to understand what differs if I add const or ignore it while returning function. Let me explain my question through an example.
const int foo()
{
return 3;
}
int main()
{
int check;
check=foo();
cout<<"before:"<<check<<endl;
check=1;
cout<<"after:"<<check<<endl;
return 0;
}
Up to now, I always think that, since I write const foo() I dont be able to change the check varaible,however I compiled it and get no error.
I wonder what I gain or loose by writing const before my foo() function.
Thanks in advance
A const modifier on primitive return types will be ignored.
See also this question: Should I return const objects?
You're not changing the variable. You're changing a copy of it.
check=foo();
assigns the value returned by foo to check. check is not const.
The difference is following compiler warning:
warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
const int foo()
^
See live demo.
This type of thing is ignored, so it has no effect.
It will make difference when you will try to return a reference.
For example:
int gGlobal;
const int & func()
{
return gGlobal;
}
int main ()
{
//Following statement will give error.
func() = 3;
return 0;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
For example, I have two functions that do the same thing:
int func(int &a)
{
return a+1;
}
and
int func2(int *a)
{
return *a+1;
}
What is the advantage of using func over func2 when calling any one of these functions?
A reference cannot be assigned null directly, but a pointer can be.
A reference cannot be reassigned to point to something else, but a pointer can be.
Both these can be advantages or disadvantages, depending on the situation.
Both of your functions are wrong. Since they don't modify the argument passed in, they should take them in as const, like this:
int func(const int &a)
{
return a+1;
}
int func2(const int *a)
{
return *a+1;
}
Now here's an advantage for references, I can pass rvalues into the reference version:
func(10);
func(func(func(10)));
I can't do that with the pointer version.
The pointer is more flexible, it can also be predefined in the declaration like:
int func2(int *a = nullptr);
Which does not work in your simple case but in many others it does.
The pointer may also more easily be used for other things, like storing in a list, typacasting it and other things.
And yes, the reference cannot be reassigned.
If a is an object that overloads standard C++ operators (e.g. operator[] or operator*), clients can use it in more standard C++ syntax like a[i], instead of a->operator[](i) or (*a)[i]