What is the use of "const" functions? [duplicate] - c++

This question already has answers here:
what does const mean in c++ in different places
(4 answers)
Functions returning a const value [duplicate]
(1 answer)
Closed 9 years ago.
This code looks weird:
const double square(double x) {
return x*x;
}
Common sense tells me that const in this context means either
the function returns a const double
OR
it promises not to change the double that was passed in. But it was passed in by value! I don't understand
OR
I know that const member functions promise not to change *this, but this is not even a member function.
Edit
What's the point to return a const double if you can save the result in a non-const variable and edit it??
double var = square(4.5); // no compile error
var = 0.3;

It is weird. As you say:
the function returns a const double
For a user-defined type, this would prevent you from modifying the return value:
square(2) += 5; // Error
although, as noted in the comments, this isn't allowed for a built-in type like double anyway. Even for user-defined types, while you probably don't want to write code like that, there's no point preventing it either.
For more complicated types, returning a const value can actually be harmful: it inhibits move semantics, since a const object can't be moved from. This could hurt performance.

That is not a "const function". It is a function which returns a value that is const. A "const function" only applies to member functions, and then the const goes on the right, after the parameter list.
The utility of this for a simple value type is dubious. However, if you were returning a reference to const or a const pointer, or something else, then it could have merit.
The only thing that returning a const of a simple type by value does is make sure that it can't be captured by non-const r-value reference in C++11. Otherwise, they'll just copy the value and be on their way.

In the example you give, and for any POD type, it makes little sense, but for more complex types it can make sense:-
const SomeClass &SomeFunction ();
which returns a reference to a const object.

A const function with const before the return value is usually used where the function returns a pointer (or perhaps a reference) to say that it will only return const pointers. This one returns a double and that means it only returns doubles that are const.

It returns a const double type variable.
If you do it like this, most compilers give a warning if you try to assign the returned value to a double type.

Related

What is the point in returning a value as const [duplicate]

This question already has answers here:
What are the use cases for having a function return by const value for non-builtin type?
(4 answers)
Closed 8 years ago.
What is the purpose of the const in this?
const Object myFunc(){
return myObject;
}
I've just started reading Effective C++ and Item 3 advocates this and a Google search picks up similar suggestions but also counterexamples. I can't see how using const here would ever be preferable. Assuming a return by value is desirable, I don't see any reason to protect the returned value. The example given for why this might be helpful is preventing unintended bool casts of the return value. The actual problem then is that implicit bool casts should be prevented with the explicit keyword.
Using const here prevents using temporary objects without assignment. So I couldn't perform arithmetic expressions with those objects. It doesn't seem like there's ever a case that an unnamed const is useful.
What is gained by using const here and when would it be preferable?
EDIT: Change arithmetic example to any function that modifies an object that you might want to perform before an assignment.
In the hypothetical situation where you could perform a potentially expensive non-const operation on an object, returning by const-value prevents you from accidentally calling this operation on a temporary. Imagine that + returned a non-const value, and you could write:
(a + b).expensive();
In the age of C++11, however, it is strongly advised to return values as non-const so that you can take full advantage of rvalue references, which only make sense on non-constant rvalues.
In summary, there is a rationale for this practice, but it is essentially obsolete.
It's pretty pointless to return a const value from a function.
It's difficult to get it to have any effect on your code:
const int foo() {
return 3;
}
int main() {
int x = foo(); // copies happily
x = 4;
}
and:
const int foo() {
return 3;
}
int main() {
foo() = 4; // not valid anyway for built-in types
}
// error: lvalue required as left operand of assignment
Though you can notice if the return type is a user-defined type:
struct T {};
const T foo() {
return T();
}
int main() {
foo() = T();
}
// error: passing ‘const T’ as ‘this’ argument of ‘T& T::operator=(const T&)’ discards qualifiers
it's questionable whether this is of any benefit to anyone.
Returning a reference is different, but unless Object is some template parameter, you're not doing that.
It makes sure that the returned object (which is an RValue at that point) can't be modified. This makes sure the user can't do thinks like this:
myFunc() = Object(...);
That would work nicely if myFunc returned by reference, but is almost certainly a bug when returned by value (and probably won't be caught by the compiler). Of course in C++11 with its rvalues this convention doesn't make as much sense as it did earlier, since a const object can't be moved from, so this can have pretty heavy effects on performance.
It could be used as a wrapper function for returning a reference to a private constant data type. For example in a linked list you have the constants tail and head, and if you want to determine if a node is a tail or head node, then you can compare it with the value returned by that function.
Though any optimizer would most likely optimize it out anyway...

C++ references and return values

I came across the following code:
class MyClass {
// various stuff including ...
double *myarray;
double &operator() (const int n){
return myarray[n];
}
double operator() (const int n) const {
return myarray[n];
}
// various other stuff ...
}
So what is the practical difference in those two overloads of "()"? I mean, I know "The first one returns a reference to a double and the second one returns a double," but what does this mean practically? When would I use the one and when would I use the other? The second one (returning a double) seems pretty safe and straightforward. Is the first one ever dangerous in some way?
They differ in that first one allows you to modify your array element, while the second one only returns value, so you can:
with: double &operator()
MyClass mm;
mm(1) = 12;
but also:
std::cout << mm(1);
with: double operator()
// mm(1) = 12; // this does not compile
std::cout << mm(1); // this is ok
also, returning a reference is more common when using operator[], like when you use std::vector::operator[].
btw. its common to have two versions of operator() - one const and second non-const. Const version will be called on const objects, while the second one on non const. But usually their signature is :
double& operator() (const int n);
const double& operator() (const int n) const;
In general, the difference between pointers and references is that pointers can be changed and can also point to nullptr, i.e. to nothing. References are fixed.
In this example, though, operator() does not return a reference but a copy of the value, i.e. changing the value retrieved that way does not change the double in the class.
If it truly returned a double&, then you could use both of these methods interchangeably (of course with different notations in the usage), and offering both would merely be a welcome convenience for the user of this class.
what does this mean practically?
It means that the second method returns by-value, i.e. it makes a copy of the array-item/double and returns that copy to the caller. The first method returns by-reference, i.e. it doesn't make a copy of the double, but rather returns a reference to the original/in-the-array double's location, which the calling code can then use to directly access the in-the-array double, if it wants to. (if it helps, the indirection semantics of the returned reference are somewhat like pointer semantics, except with a syntax that is more similar to the traditional C/C++ by-value functionality)
When would I use the one and when would I use the other?
The by-value method is safer, since there is less chance of invoking undefined behavior; the by-reference method gives you some more flexibility (i.e. the caller could then update the item in the array by writing to the reference he received as a return value) and it might be more efficient in some situations (e.g. returning a reference avoids the need to copy the object, which could be an expensive operation if the object is large or complex). For a small object like a double, returning by-value is likely more efficient than returning by-reference.
Is the [by-reference method] ever dangerous in some way?
It can be -- for example, if you were to return a reference to an automatic/stack variable, that would cause undefined behavior, since the variable would be destroyed before the calling code could use it:
double & dont_ever_do_this()
{
double x = 5.0; // x will be destroyed as this method returns!
return x; // so returning a reference to x is a silly thing to do
}
Similarly, in your MyClass example, if the caller holds on to the returned reference and then tries to use it after myarray has been deleted, the caller will be reading from (or writing to) a memory location that is no longer valid, and that will cause undefined behavior (read: Bad Things) to happen.
And of course returning a non-const reference means the caller has the ability to change the contents of the returned array item without your class being aware of it, which might not be something you want to allow.
You can see value categories from this link.
http://en.cppreference.com/w/cpp/language/value_category
In double& operator() case you have lvalue expression and can use like lvalue (for assignment, print etc.)
MyClass class;
class(7) = 21;
or
std::cout << class(7);
And in double operator() const case you have rvalue expression.
In this case you also can use it with const object.

How to resolve this "cast to pointer from type of different size" warning?

I have two programs that communicate over the D-Bus. In one of the there is a function that takes two parameters namely const char* data and int size and in another one I have a function that returns a value of the type unsigned char. I place a function call in the first program like this function((char*)program2->function().value(), 1) but i get the warning cast to pointer from integer of different size [-Wint-to-pointer-cast]. how should i resolve this warning? also I'm using Qt libraries.
EDIT:
actually in the function that takes the const char* and int I append the data to a QByteArray which accepts const char* and a size of type int in it's constructor as provided by Qt and the other program is supposed to return a number in the range 0-255 hence the unsinged char. If what I'm doing is wrong what's the best way to obtain the desired result?
Also call to program2->function invokes the following:
inline QDBusPendingReply<uchar> type()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QLatin1String("type"), argumentList);
}
this class has a function called value() which invokes:
inline typename Select<0>::Type value() const
{
return argumentAt<0>();
}
NOTE: my main purpose of this question was to find out a way to create a reference to the returned result of calling a function defined within the proxy class not how to convert it to something acceptable for creation of a QByteArray so please stop adding unrelated tags like QByteArray or QtCore etc.
What you need is the address of the data... which would look like
function2(& program2->function().value(), 1);
and would be perfectly safe, since the lifetime of the temporary variable is until the end of the complete expression, which is long enough1 for function2 to use it.
Unfortunately, you can't use the & address-of operator on an rvalue. But there is a workaround, since you can bind a const lvalue reference to an rvalue, and you want a pointer to const data anyway:
template<T>
const T* get_addr(const T& v) { return &v; }
function2( get_addr(program2->function().value()), 1 );
If you get a signed-vs-unsigned, mismatch, try
function2( get_addr<char>(program2->function().value()), 1 );
Of course this is a lot of work just to avoid giving the variable a name, as Captain Obvlious has done.
1 Unless function2 saves that pointer for later, but if it does then you shouldn't be using a local variable to hold the value either, but pay very close attention to object lifetime.
I do not think what you are doing is safe, hence your code might not work at all. If your function() is returning an "unsigned char", its going to make a copy of it and return it. At the same time your other function() is taking a "const char*". I suggest to modify your program2->function() to return a "char *".
Converting an integer to a pointer is not a really good idea especially if you don't know why the conversion is necessary and what exactly it does. It looks like the conversion isn't even necessary and you really need a solution to properly call the function instead of fixing the cast warning. From the code and description you provided it appears you want to send a single byte returned by the call to program2->function(). Since the value returned by this function is an rvalue you can't directly take it's address. Instead you can to store it in a variable and then pass a pointer to that instead. Something like the code below should let you do what you want.
char value = program2->function();
function(&value, 1);

Purpose of returning by const value? [duplicate]

This question already has answers here:
What are the use cases for having a function return by const value for non-builtin type?
(4 answers)
Closed 8 years ago.
What is the purpose of the const in this?
const Object myFunc(){
return myObject;
}
I've just started reading Effective C++ and Item 3 advocates this and a Google search picks up similar suggestions but also counterexamples. I can't see how using const here would ever be preferable. Assuming a return by value is desirable, I don't see any reason to protect the returned value. The example given for why this might be helpful is preventing unintended bool casts of the return value. The actual problem then is that implicit bool casts should be prevented with the explicit keyword.
Using const here prevents using temporary objects without assignment. So I couldn't perform arithmetic expressions with those objects. It doesn't seem like there's ever a case that an unnamed const is useful.
What is gained by using const here and when would it be preferable?
EDIT: Change arithmetic example to any function that modifies an object that you might want to perform before an assignment.
In the hypothetical situation where you could perform a potentially expensive non-const operation on an object, returning by const-value prevents you from accidentally calling this operation on a temporary. Imagine that + returned a non-const value, and you could write:
(a + b).expensive();
In the age of C++11, however, it is strongly advised to return values as non-const so that you can take full advantage of rvalue references, which only make sense on non-constant rvalues.
In summary, there is a rationale for this practice, but it is essentially obsolete.
It's pretty pointless to return a const value from a function.
It's difficult to get it to have any effect on your code:
const int foo() {
return 3;
}
int main() {
int x = foo(); // copies happily
x = 4;
}
and:
const int foo() {
return 3;
}
int main() {
foo() = 4; // not valid anyway for built-in types
}
// error: lvalue required as left operand of assignment
Though you can notice if the return type is a user-defined type:
struct T {};
const T foo() {
return T();
}
int main() {
foo() = T();
}
// error: passing ‘const T’ as ‘this’ argument of ‘T& T::operator=(const T&)’ discards qualifiers
it's questionable whether this is of any benefit to anyone.
Returning a reference is different, but unless Object is some template parameter, you're not doing that.
It makes sure that the returned object (which is an RValue at that point) can't be modified. This makes sure the user can't do thinks like this:
myFunc() = Object(...);
That would work nicely if myFunc returned by reference, but is almost certainly a bug when returned by value (and probably won't be caught by the compiler). Of course in C++11 with its rvalues this convention doesn't make as much sense as it did earlier, since a const object can't be moved from, so this can have pretty heavy effects on performance.
It could be used as a wrapper function for returning a reference to a private constant data type. For example in a linked list you have the constants tail and head, and if you want to determine if a node is a tail or head node, then you can compare it with the value returned by that function.
Though any optimizer would most likely optimize it out anyway...

Should I return bool or const bool?

Which is better:
bool MyClass::someQuery() const;
const bool MyClass::someQuery() const;
I've been using 'const bool' since I'm sure I remember hearing it's "what the ints do" (for e.g. comparison operators) but I can't find evidence of that anywhere, mostly due to it being difficult to Google and Intellisense not helping out any ;) Can anyone confirm that?
To me returning const values (this isn't just about bools) makes more sense; it'll prevent temporaries being modified, which is almost always going to be a programmer mistake. I just want something to back that up so I can extol returning const values to my colleagues :)
This is the case when const adds no value but inflates the code and makes the reader think more. What's the point of this const? The caller can copy the value into some non-const variable and do whatever he wants with it anyway.
So you know it's right, you're just after the Voice of Authority?
Preventing accidental modification of temporaries is very valuable. In general, you should declare as many things as you possibly can const, it protects you from a variety of accidents and gives the optimiser useful hints.
D'you have a copy of Scott Meyers' "Effective C++" around? Point them at Item 3 (page 18 in the third edition) ;)
It gives the example of
class Rational {...};
const Rational operator* (const Rational& lhs, const Rational& rhs );
if( (a * b) = c ) // declaring operator *'s return value const causes error to be caught by compiler
Note that if((a*b) = c) won't compile for built-in types anyway, so it is very relevant here whether we're talking built-in types (your question asks for bool) or user-defined types.
For built-in types it makes no sense at all, so it shouldn't be used. And for user-defined types, I'm in jalf's camp: What if the caller wants to modify the returned object?
I'm not convinced that if((a*b) = c) is such a good argument for returning const user-defined types, since I can't remember the last time I've seen a compiler not warn about this.
To be a little more specific, only "objects" can be const. The C++ standard's definition of "object" includes everything an lvalue refers to ("has a name") and class-type temporaries. A boolean return value is an rvalue of a non-class type which is why a standards-compliant compiler will just ignore "const" in this case. As others said already, it's useless in this context.
When you returning a refernce to a member variable it makes sense to make it const. Here you are returning a copy, hence there is no need of const.
The const modifier is only used for return types that are returned by reference (either as reference const SomeObject& or via a pointer const SomeObject*), so the caller won't be able to modify the object via the reference/pointer. Primitive types are returned by value, which means that the caller receives a copy of the the object, not the object itself.
Therefore, const is not really appropriate for returned value types. Since the copy is outside of the control of the called function, the called function should not dictate to the caller that it cannot be changed.
This is an ancient post, but I think it's worth mentioning there is a potential corner case here since C++11. While, as stated by others, it will make no difference whether you use const bool or bool as return type in most cases, if you are using C++11 decltype and associates, e.g. result_of, you could declare a variable with the same type as the returning value of some function, and so the const would actually have an effect in this case.
It completely doesn't matter. Therefore, the consensus is to return just bool.
The reason that it doesn't matter is that you can't call non-const member functions anyway; bool is not a class or struct.
As bool is going to be copied, it's the same, to put const or not. Plus you'll may have some compil problems.
const return type
SUMMARY:
The value of a return type that is
declared const cannot be changed. This
is especially usefull when giving a
reference to a class’s internals, but
can also prevent rarer errors.
const bool func();
bool f = func();
0 errors, 0 warnings. What have you accomplished other than unnecessary code inflation?