Miguel Figueiredo Miguel Figueiredo - 1 month ago 6
C Question

Qsort array | warning: initialization discards qualifiers from pointer target type

I am compiling this program in GCC, using Wall command and it appears all clear. But my college online platform is giving a compile time error

9.c: In function 'compare_int':
9.c:8: warning: initialization discards qualifiers from pointer target type
9.c:9: warning: initialization discards qualifiers from pointer target type

Here's the code

#include <stdio.h>
#include <stdlib.h>
#define MAX 1000

int c=0;

int compare_int(const void *pa, const void *pb) {
const int ((*a)[1]) = pa;
const int ((*b)[1]) = pb;
if ( (*a)[0] < (*b)[0] ) return -1;
if ( (*a)[0] > (*b)[0] ) return +1;
return 0;
}

void check(int m, int lastNum, int startIndex, int v[][2], int n){
if (lastNum >= m) printf("%d\n", c);
else{
int i,max=0;
for (i=startIndex;v[i][0]<=lastNum;i++){
if (v[i][0] <= lastNum)
if (v[i][1] > max) max = v[i][1];
}
c++;
check(m, max, i,v, n);
}
}

int main(){
int m,n,i;
int line[MAX][2];
scanf("%d", &m);
scanf("%d", &n);
for (i=0;i<n;i++){
scanf("%d %d", &line[i][0], &line [i][1]);
}
qsort(line, n, sizeof line[0], compare_int);
check(m, 0, 0, line, n);
return 0;
}


The program is supposed to read 2 numbers. First one is the length of a path starting in 0, and the second one is the number of pairs(not ordered) that can fill it. Then using greedy algorithm it has to find how many segments it needs to fullfill it. The problem here is on quick sorting the matrix with pairs, apparently it has some pointer error but I can't find what's wrong here... I guess it's somewhat basic but I can't understand it at all.

Help please!

Answer

The compiler is complaining about the initializations of local variables a and b in this fragment:

int compare_int(const void *pa, const void *pb) {
  const int ((*a)[1]) = pa;
  const int ((*b)[1]) = pb;

The compiler is right. Mostly.

Consider variable a. Cdecl interprets its declaration like so:

declare a as pointer to array 1 of const int

Note in particular that it is not a itself that is const (there is no way to declare an array const); rather, it is the elements of a that are const. This is a distinction without much difference, except to a picky compiler that observes that function parameter pa is declared as a pointer to a const object, and a is declared as a pointer to a non-const object, so that assigning the former to the latter loses (technically) the const-ness.

The best solution is probably to stop trying to be so clever. Why declare a and b as pointers to one-element arrays, when the whole point is to compare the objects they point to (as ints)? You have to roll out tricky syntax in the local variable declarations and also everywhere you use the values. I'd just do this:

int compare_int(const void *pa, const void *pb) {
   int a = *(const int *)pa;
   int b = *(const int *)pb;

   if ( a < b ) return -1;
   // ...
Comments