C++ Syntax : Constant Reference Parameter - c++

Please explain const void *a, const void *b on the code bellow. Are these constant reference parameters - meaning the inner code of this function cannot change its value? Why make these parameters a reference? Thought a reference parameter is meant to be for pass by value and allow value to be change inside the function definition. Why use void for a parameter argument?
int peak_compare(const void *a, const void *b) //Function peak_compare
{
Peaks *aa = (Peaks *)a;
Peaks *bb = (Peaks *)b;
if(aa->wt1 > bb->wt1) return -1;
if(aa->wt1 == bb->wt1) return 0;
return 1;
}
Thanks for any advise.

const typename * p is the syntax for Pointer to Constant. This means that, you cannot change the value in the function.
typename * const p is the syntax for Constant Pointer. This means that you cannot change the pointer itself in the function.
In the above examples, typename can be anything from standard types to user defined types, to void. If it is a void, the intention is that the function might get pointers to different types. You should properly cast the void pointer to correct type in order to access its members, as in your case the following lines are doing:
Peaks *aa = (Peaks *)a;
Peaks *bb = (Peaks *)b;
But this cast loses the const-ness. The correct syntax should be:
const Peaks *aa = (const Peaks *)a;
const Peaks *bb = (const Peaks *)b;
not to lose the value const-ness.
EDIT:
As one of the comments point out, and since the question is only tagged with C++, the cast is better done in C++ style as follows:
const Peaks* aa = static_cast<const Peaks*>(a);
const Peaks* bb = static_cast<const Peaks*>(b);

const void *a means a is a void pointer to constant, so the content cannot be change.
See this link for explanation:
http://en.wikipedia.org/wiki/Const-correctness
BUT there is a dangerous cast after as you loose the const content with your cast.
Peaks *aa = (Peaks *)a;
Should be changed to
const Peaks *aa = (const Peaks *)a;

Compare two void pointers, returning an integer greater than, equal to, or less than 0, according to whether the key of a is greater than, equal to, or less than the key of b as determined by comparing them with peak_compare().

There is no type safety while using arguments of type void* whether it's const or not. You should avoid using C-style casts as much as possible.
Peaks* aa = (Peaks*) a;
might lead to aa being invalid, which will result into undefined behavior.
In case you need this function because of qsort, then I recommend you to use std::sort instead.
In that case you could just override the operator< of Peaks:
struct Peaks
{
bool operator < (const Peaks& p) const
{
return (wt1 < p.wt1);
}
};
which could be possibly used like this:
std::vector<Peaks> vec;
...
std::sort(vec.begin(), vec.end());
Also have a look at Sorting a vector of custom objects :)

They are pointers to constant data, correct, see here so you cannot change the value of the thing they point to through the pointer.

Related

Why are const used so frequently in C++?

Recently i was looking for a solution to sort only the values of map and then i found this code
template <typename T1, typename T2>
struct less_second {
typedef pair<T1, T2> type;
bool operator ()(type const& a, type const& b) const {
return a.second < b.second;
}
};
map<string, int> mymap;
// …
vector<pair<string, int> > mapcopy(mymap.begin(), mymap.end());
sort(mapcopy.begin(), mapcopy.end(), less_second<string, int>());
The first thing that stuck my mind was why in many sample code and solutions I find people frequently using the const keyword is it a good practice to do that, if so why?
Why use const?
My take is that you should try to use const as much as you can. Mutable values are always a source of errors. You can avoid these errors by avoiding mutable values.
Function of const in C++
const is used a lot because it has a lot off different meanings:
If we look at this signature, we can see two types of const bool operator ()(type const& a, type const& b) const {...}: There is a const reference const &a and const &b, which just means that you cannot modify a or b, which you passed as reference.
There is also the const at the end of the method, which means that this method does not modify the instance. Figure a get-method. This method will not modify the instance it gets the value from. You can signal this to the caller by using T get_element(int at_index) const {...}.
There are further const pointers.
Here you could change the value in the address, but not the address itself:
int *const a = new int;
*a = 1; // legal
a = &var; // illegal
Here you can change the address the pointer is pointing to, but not the value in that address.
const int *a = new int;
*a = 1; // illegal
a = &var; // legal
(Hope I did not confuse the two)
Have a pointer that does not allow any change:
const int * const a = new int;
*a = 1; // illegal
a = &var; // illegal
Further reading:
When to use constant pointers instead of const references.
YT - Const in C++
There is furthermore constexpr, which can calculate a value at compile time. This is different than the const keyword, and might confuse you at the beginning.
The const in the parameters of this function allows the function to be called with const values (in the case of int a value like 1 is const). And also since the parameters are a reference, the const guarantees that the original variables will not be changed.
The const after the member function declaration, guarentees that an object of that class is not modified when that function is called.
So by looking at the definition of the function, we can automatically know the guarentees and what type of variables we can use.
Also knowing these assumptions, the compiler can create better code.

Find a pointer in a std::set based on a const pointer [duplicate]

Is there any good way to obviate the const_cast below, while keeping const correctness?
Without const_cast the code below doesn't compile. set::find gets a const reference to the set's key type, so in our case it guarantees not to change the passed-in pointer value; however, nothing it guaranteed about not changing what the pointer points to.
class C {
public:
std::set<int*> m_set;
bool isPtrInSet(const int* ptr) const
{
return m_set.find(const_cast<int*>(ptr)) != m_set.end();
}
};
Yes.
In C++14, you can use your own comparator that declares int const* as transparent. This would enable the template overload of find() that can compare keys against arbitrary types. See this related SO question. And here's Jonathan Wakely's explanation.
I want to explain the underlying logic of why this is impossible.
Suppose set<int*>::find(const int*) would be legitimate. Then you could do the following:
set<int*> s;
const int* p_const;
// fill s and p
auto it = s.find(p_const);
int* p = *it;
Hey presto! You transformed const int* to int* without performing const_cast.
Is there any good way to obviate the const_cast below, while keeping const correctness?
I am not sure whether what I am going to suggest qualifies as a "good way". However, you can avoid the const_cast if you don't mind iterating over the contents of the set yourself. Keep in mind that this transforms what could be an O(log(N)) operation to an O(N) operation.
bool isPtrInSet(const int* ptr) const
{
for ( auto p : m_set )
{
if ( p == ptr )
{
return true;
}
}
return false;
}

What would be an use case for a function returning a const pointer (int * const, for example)?

The title is self explanatory, but I'll give an example anyways.
int sum(int a, int b){
return a + b;
}
We could rewrite it as
int sum(const int a, const int b){
return a + b;
}
But what about returning a const int? Is it useful in any way?
const int sum(const int a, const int b){
return a + b;
}
The caller will have to copy the const return to a const lvalue. Is this too restrictive? Do you know any use cases where this could be a good design choice?
Ok, I wasn't clear at the question body. Think about a sum function that works similar to assembly add:
int *sum(int *a, int b){
*a += b;
return a;
}
Add the const's to the params:
int *sum(int * const a, const int b){
*a += b;
return a;
}
What about making the return const too? Is there a reason for this?
There are a lot of situations where you may return a const pointer or a const object. I can't imagine any real situation where you want to return a primitive type as const.
I'm not sure what's your question, in the title your' talking about int* const but in the code example you have a const int.
Some examples (in C++) follows for different combinations of const and T*.
Pointer to const (primitive type)
const int* someFuncion();
You have a pointer to a constant, it means you can change the pointer but you can't change the pointed object/value. Please note that someFunction() must not return a pointer (const or not) to a stack allocated variable. I assume the pointer is valid. For example:
const int* value = someFunction();
// Next line is valid, value will hold a new pointer
value = anotherFunction();
// Next line is not valid, pointed value cannot be changed
*value = 10;
Pointer to const (object)
const T* someFunction();
You have a pointer to a constant. It means you can change the pointer to point to another object but you can't change the pointed object state. This doesn't mean you can't use that object, only that the object is const then you can use only its methods marked as const, read its fields and write its mutable fields. A constant method is defined as:
void method() const;
It can have any return type and any parameter the point is that it's marked with the const modifier. It means that it won't change the object state (again with the exclusion of mutable objects).
Now an example, with T declared as:
class T
{
public:
void dump() const
{
// Dump the value to console, for example
}
void increaseValue()
{
++m_value;
}
private:
int m_value;
};
Imagine to write following code:
const T* value = someMethod();
// Next line is valid, value will hold a new pointer
value = anotherMethod();
// Next line is not valid, we cannot change the object state
value->increaseValue();
// Next line is valid, we do not change the object state
value->dump();
Constant pointer (primitive type)
int* const someFunction();
You have a constant pointer, it means you can change the pointed value but you cannot assign another memory location to the pointer itself. For example:
int* const value = someFunction();
// Next line is not valid, value cannot be changed
value = anotherFunction();
// Next line is valid, you can change the variable pointed by value
*value = 10;
Constant pointer (object)
T* const someFunction();
You have a constant pointer, it means you can change the pointed object state but you cannot assign another memory location to the pointer itself. For example:
T* const value = someFunction();
// Next line is not valid, value cannot be changed
value = anotherFunction();
// Next lines are both valid, we can do whatever we want with the object
value->increaseValue();
value->dump();
Constant pointer to a constant
const int* const someFunction();
This is the mix of previous declarations. All (restrictive) rules described above are valid. It means you can't change the pointer and you can't change the pointed value.
Notes
The const modifier is not restricted to be used to pointers and functions return value. For example:
// PI value cannot be changed
const int PI = 3.14f;
// I have a pointer to a constant value
const* int pPI = &PI;
// I have a constant pointer to a constant value, note that
const* int const pPI2 = &PI;
Remember that the const modifier can always be removed using a C-style cast or a const_cast.
Conclusions
So, going back to your question, is it useful a function with a const int return value?
If it's a pointer my answer is yes, even if it can be removed with a cast: the purpose of const is to communicate intentions (saving you from stupid errors hard to find) so more your function communicates and better it'll be used. Updating this from your last example my answer is yes, use const wherever appliable. Who will call your code will thank you (and you'll do it with yourself).
If it's just a const int (or another primitive type) it may be very rare you have to write something like that. Very often they're just intermediate results of a long calculation then it's useless to declare them as const (primitive types won't change but will be combined to create a new value). Note, however, that if it make some sense to declare them as const then you should do it. I guess it's more common to see a constant primitive type declared as local variable (again to be sure it won't be changed by mistake). For example:
// This local variable cannot be modified
const int rate = (calculateX() + calculateY()) / calculateRateFactor();
Or in functions, why not? If you always use this rule (const if shouldn't be changed) you'll see on-the-fly when a parameter isn't const then you'll understand you'll modify it somewhere (maybe with a small, hidden, pretty ++ at the most right character of your screen).
// With this prototype I'm sure I won't change a or b by mistake inside
// the function body.
int someFunction(const int a, const int b);
For objects I think it's even more common to use the const modifier (because a const T return type makes sense very often), for example:
// This object cannot be changed, just moved all around
const order* getNextOrderToStore();
Topic isn't ended, of course, because of aliases, mutables, operators overloading and the differences between C and C++...
I can only see this as a good thing as a statement of intent.
Something more in the sense of - if you get this value, you shouldn't need to change it, more than don't change this value.
This actually accomplishes nothing other than intent, as you're able to change the value anyway: http://ideone.com/Mf8Ge
No, I see few situations where this would be useful, as it really accomplishes nothing, and it restricts what the caller can do with the return value.
The caller will have to copy the const return to a const lvalue.
No, it won't at all. In fact, it might not ever copy it. Or it might copy it to a mutable lvalue.
There is no sense in const rvalues, there never has been, and there never will be.

Const before or const after?

To start you probably know that const can be used to make either an object's data or a pointer not modifiable or both.
const Object* obj; // can't change data
Object* const obj; // can't change pointer
const Object* const obj; // can't change data or pointer
However you can also use the syntax:
Object const *obj; // same as const Object* obj;
The only thing that seems to matter is which side of the asterisk you put the const keyword. Personally I prefer to put const on the left of the type to specify it's data is not modifiable as I find it reads better in my left-to-right mindset but which syntax came first?
More importantly why is there two correct ways of specifying const data and in what situation would you prefer or need one over the other if any?
Edit:
So it sounds like this was an arbitrary decision when the standard for how compilers should interpret things was drafted long before I was born. Since const is applied to what is to the left of the keyword (by default?) I guess they figured there was no harm in adding "shortcuts" to apply keywords and type qualifiers in other ways at least until such a time as the declaration changes by parsing a * or & ...
This was the case in C as well then I'm assuming?
why is there two correct ways of specifying const data and in what situation would you prefer or need one over the other if any?
Essentially, the reason that the position of const within specifiers prior to an asterisk does not matter is that the C grammar was defined that way by Kernighan and Ritchie.
The reason they defined the grammar in this way was likely that their C compiler parsed input from left-to-right and finished processing each token as it consumed that. Consuming the * token changes the state of the current declaration to a pointer type. Encountering const after * means the const qualifier is applied to a pointer declaration; encountering it prior to the * means the qualifier is applied to the data pointed to.
Because the semantic meaning does not change if the const qualifier appears before or after the type specifiers, it is accepted either way.
A similar sort of case arises when declaring function pointers, where:
void * function1(void) declares a function which returns void *,
void (* function2)(void) declares a function pointer to a function which returns void.
Again the thing to notice is that the language syntax supports a left-to-right parser.
The rule is:
const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.
I prefer using const on the right of the thing to be const just because it is the "original" way const is defined.
But I think this is a very subjective point of view.
I prefer the second syntax. It helps me keep track of 'what' is constant by reading the type declaration from right to left:
Object * const obj; // read right-to-left: const pointer to Object
Object const * obj; // read right-to-left: pointer to const Object
Object const * const obj; // read right-to-left: const pointer to const Object
The order of the keywords in a declaration isn't all that fixed. There are many alternatives to "the one true order". Like this
int long const long unsigned volatile i = 0;
or should it be
volatile unsigned long long int const i = 0;
??
The first rule is to use whichever format your local coding standards
requires. After that: putting the const in front leads to no end of
confusion when typedefs are involved, e.g.:
typedef int* IntPtr;
const IntPtr p1; // same as int* const p1;
If your coding standard allows typedef's of pointers, then it really
should insist on putting the const after the type. In every case but
when applied to the type, const must follow what it applies to, so
coherence also argues in favor of the const after. But local coding
guidelines trump all of these; the difference isn't normally important
enough to go back and change all of the existing code.
There are historical reasons that either left or right is acceptable. Stroustrup had added const to C++ by 1983, but it didn't make it to C until C89/C90.
In C++ there's a good reason to always use const on the right. You'll be consistent everywhere because const member functions must be declared this way:
int getInt() const;
C uses a right-to-left syntax. Just read the declarations from right to left:
int var = 0;
// one is a pointer to a const int
int const * one = &var;
// two is a pointer to an int const (same as "const int")
const int * two = &var;
// three is a constant pointer to an int
int * const three = &var;
The first thing left to the "const" is affected by it.
For more fun read this guide:
http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html
With
using P_Int = int *;
P_Int const a = nullptr;
int * const b = nullptr;
const P_Int c = nullptr;
const int * d = nullptr;
the variables a and b are the same type as each other but, somewhat confusingly, the variables c and d are not the same type as each other. My preference is for the first scenario, without the confusion: have const on the right of the type. N.B. it is the pointer that is const with a, b, and c; but the int is const with d.
When I work with the existing code, I follow the way already being used which is most of the time, const on left e.g const int a = 10; but if I got a chance to work from start I choose the "right way", means const on right e.g int const a = 10;, which is a more universal approach and straightforward to read.
As mentioned already, the rule is
const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.
Here is the example code for basic use cases.
int main() {
int const a = 10; // Constant integer
const int b = 20; // Constant integer (same as above)
int c = 30; // Integer (changeable)
int * const d = &c; // Constant pointer to changeable integer
int const * e = &a; // Changeable pointer to constant integer
int const * const f = &a; // Constant pointer to constant integer
return 0;
}
At the end of the day, if there is no guideline to follow, this is subjective, and harmless to use either approach.

'const int' vs. 'int const' as function parameters in C++ and C

Consider:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
Are these two functions the same in every aspect or is there a difference?
I'm interested in an answer for the C language, but if there is something interesting in the C++ language, I'd like to know as well.
The trick is to read the declaration backwards (right-to-left):
const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"
Both are the same thing. Therefore:
a = 2; // Can't do because a is constant
The reading backwards trick especially comes in handy when you're dealing with more complex declarations such as:
const char *s; // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"
*s = 'A'; // Can't do because the char is constant
s++; // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++; // Can't do because the pointer is constant
const T and T const are identical. With pointer types it becomes more complicated:
const char* is a pointer to a constant char
char const* is a pointer to a constant char
char* const is a constant pointer to a (mutable) char
In other words, (1) and (2) are identical. The only way of making the pointer (rather than the pointee) const is to use a suffix-const.
This is why many people prefer to always put const to the right side of the type (“East const” style): it makes its location relative to the type consistent and easy to remember (it also anecdotally seems to make it easier to teach to beginners).
There is no difference. They both declare "a" to be an integer that cannot be changed.
The place where differences start to appear is when you use pointers.
Both of these:
const int *a
int const *a
declare "a" to be a pointer to an integer that doesn't change. "a" can be assigned to, but "*a" cannot.
int * const a
declares "a" to be a constant pointer to an integer. "*a" can be assigned to, but "a" cannot.
const int * const a
declares "a" to be a constant pointer to a constant integer. Neither "a" nor "*a" can be assigned to.
static int one = 1;
int testfunc3 (const int *a)
{
*a = 1; /* Error */
a = &one;
return *a;
}
int testfunc4 (int * const a)
{
*a = 1;
a = &one; /* Error */
return *a;
}
int testfunc5 (const int * const a)
{
*a = 1; /* Error */
a = &one; /* Error */
return *a;
}
Prakash is correct that the declarations are the same, although a little more explanation of the pointer case might be in order.
"const int* p" is a pointer to an int that does not allow the int to be changed through that pointer. "int* const p" is a pointer to an int that cannot be changed to point to another int.
See https://isocpp.org/wiki/faq/const-correctness#const-ptr-vs-ptr-const.
const int is identical to int const, as is true with all scalar types in C. In general, declaring a scalar function parameter as const is not needed, since C's call-by-value semantics mean that any changes to the variable are local to its enclosing function.
They are the same, but in C++ there's a good reason to always use const on the right. You'll be consistent everywhere because const member functions must be declared this way:
int getInt() const;
It changes the this pointer in the function from Foo * const to Foo const * const. See here.
Yes, they are same for just int
and different for int*
This isn't a direct answer but a related tip. To keep things straight, I always use the convection "put const on the outside", where by "outside" I mean the far left or far right. That way there is no confusion -- the const applies to the closest thing (either the type or the *). E.g.,
int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change
I think in this case they are the same, but here is an example where order matters:
const int* cantChangeTheData;
int* const cantChangeTheAddress;