2

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.

sintiaWeb
  • 23
  • 2
  • *"Why use `void` for a parameter argument?"* - the type used here is actually `void*` and I don't understand this decision of the author of this code either. – LihO Mar 14 '13 at 17:36
  • 2
    The function is probably meant to be used with C algorithms like [`qsort`](http://en.cppreference.com/w/cpp/algorithm/qsort) and [`bsearch`](http://en.cppreference.com/w/cpp/algorithm/bsearch). – Benjamin Lindley Mar 14 '13 at 17:39
  • 1
    and the casts to non-const are evil. use `const Peaks *` – WhozCraig Mar 14 '13 at 17:41
  • So would have it been wise to use the function signature like this? int peak_compare(const Peaks *a, const Peaks *b) if not, what are the advantages of using void for a type? – sintiaWeb Mar 14 '13 at 18:32
  • If the intention is, as I suspect, to use the function with C algorithms like qsort and bsearch, then that signature wouldn't work for it. – Benjamin Lindley Mar 14 '13 at 20:58

5 Answers5

2

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);
meyumer
  • 5,063
  • 1
  • 17
  • 21
0

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;
TridenT
  • 4,879
  • 1
  • 32
  • 56
0

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().

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
0

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 :)

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
-1

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

Dutts
  • 5,781
  • 3
  • 39
  • 61