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.

5
  • "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. Commented Mar 14, 2013 at 17:36
  • 2
    The function is probably meant to be used with C algorithms like qsort and bsearch. Commented Mar 14, 2013 at 17:39
  • 1
    and the casts to non-const are evil. use const Peaks * Commented Mar 14, 2013 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? Commented Mar 14, 2013 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. Commented Mar 14, 2013 at 20:58

5 Answers 5

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);
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! well explained.
For C++ I would recommend C++-style casts: const Peaks* aa = static_cast<const Peaks*>(a);
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;

Comments

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

1 Comment

This summarizes the overall function. Thanks!
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 :)

Comments

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

1 Comment

Thanks the link was very informative and clarify my question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.