Originally Posted by
HelpMeC
@laserlight
First, thank you.
I'm really confused by now.
I have attached the image to the exercise as given.
- Now you have turned my attention to the copy:
We are really modifying the content of the elements - so, how is it legal to swap the elements (which are const void*) of the arrToSort in genSort function?
Thank you!
How is that legal?! It doesn't even compile!
Code:
#include <stdio.h>
#include <assert.h>
typedef void* Element;
typedef const void* ConstElement;
void genSort(Element arrToSort, int arrSize, int (*less)(ConstElement, ConstElement))
{
int numOfPasses;
if (arrSize < 2)
return;
for (numOfPasses = 0 ; numOfPasses < arrSize ; ++numOfPasses) {
int it;
for (it = 0 ; it < arrSize - 1 ; ++it) {
if (less(arrToSort[it+1], arrToSort[it]))
{
Element temp = arrToSort[it+1];
arrToSort[it+1] = arrToSort[it];
arrToSort[it] = temp;
}
}
}
}
int IntLess(ConstElement a, ConstElement b) {
int *i1 = (int*) a;
int *i2 = (int*) b;
assert(i1 != NULL && i2 != NULL);
return (*i1 < *i2);
}
int main() {
int A[5] = {5, 6, 2, 23, 9};
int tempi;
ConstElement arrToSort[5];
for (tempi = 0 ; tempi < 5 ; ++tempi)
arrToSort[tempi] = A + tempi;
genSort(arrToSort, 5, &IntLess);
/* will print 2 */
printf("arrToSort[0] = %d\n", *((int *) arrToSort[0]));
return 0;
}
$ gcc -Wall isort.c
isort.c: In function ‘genSort’:
isort.c:17:31: warning: dereferencing ‘void *’ pointer
17 | if (less(arrToSort[it+1], arrToSort[it]))
| ^
isort.c:17:48: warning: dereferencing ‘void *’ pointer
17 | if (less(arrToSort[it+1], arrToSort[it]))
| ^
isort.c:17:31: error: invalid use of void expression
17 | if (less(arrToSort[it+1], arrToSort[it]))
| ~~~~~~~~~^~~~~~
isort.c:17:48: error: invalid use of void expression
17 | if (less(arrToSort[it+1], arrToSort[it]))
| ~~~~~~~~~^~~~
isort.c:19:41: warning: dereferencing ‘void *’ pointer
19 | Element temp = arrToSort[it+1];
| ^
isort.c:19:32: error: void value not ignored as it ought to be
19 | Element temp = arrToSort[it+1];
| ^~~~~~~~~
isort.c:20:26: warning: dereferencing ‘void *’ pointer
20 | arrToSort[it+1] = arrToSort[it];
| ^
isort.c:20:44: warning: dereferencing ‘void *’ pointer
20 | arrToSort[it+1] = arrToSort[it];
| ^
isort.c:20:33: error: invalid use of void expression
20 | arrToSort[it+1] = arrToSort[it];
| ^
isort.c:21:26: warning: dereferencing ‘void *’ pointer
21 | arrToSort[it] = temp;
| ^
isort.c:21:31: error: invalid use of void expression
21 | arrToSort[it] = temp;
Also, if you fix things and change line 9 to (adding the * before arrToSort)
Code:
void genSort(Element *arrToSort, int arrSize, int (*less)(ConstElement, ConstElement))
It will compile but discards the const qualifiers all over the place:
Code:
$ gcc -Wall isort.c
isort.c: In function ‘main’:
isort.c:42:13: warning: passing argument 1 of ‘genSort’ from incompatible pointer type [-Wincompatible-pointer-types]
42 | genSort(arrToSort, 5, &IntLess);
| ^~~~~~~~~
| |
| const void **
isort.c:9:23: note: expected ‘void **’ but argument is of type ‘const void **’
9 | void genSort(Element *arrToSort, int arrSize, int (*less)(ConstElement, ConstElement))
| ~~~~~~~~~^~~~~~~~~
The correct code is:
Code:
#include <stdio.h>
#include <assert.h>
typedef void* Element;
typedef const void* ConstElement;
/* !!!!!!!!!!!! CHANGED to Element *arrToSort */
void genSort(Element *arrToSort, int arrSize, int (*less)(ConstElement, ConstElement))
{
int numOfPasses;
if (arrSize < 2)
return;
for (numOfPasses = 0 ; numOfPasses < arrSize ; ++numOfPasses) {
int it;
for (it = 0 ; it < arrSize - 1 ; ++it) {
if (less(arrToSort[it+1], arrToSort[it]))
{
Element temp = arrToSort[it+1];
arrToSort[it+1] = arrToSort[it];
arrToSort[it] = temp;
}
}
}
}
int IntLess(ConstElement a, ConstElement b) {
int *i1 = (int*) a;
int *i2 = (int*) b;
assert(i1 != NULL && i2 != NULL);
return (*i1 < *i2);
}
int main() {
int A[5] = {5, 6, 2, 23, 9};
int tempi;
Element arrToSort[5]; /* !!!!!!!!!!!!!! CHANGED */
for (tempi = 0 ; tempi < 5 ; ++tempi)
arrToSort[tempi] = A + tempi;
genSort(arrToSort, 5, &IntLess);
/* will print 2 */
printf("arrToSort[0] = %d\n", *((int *) arrToSort[0]));
return 0;
}
Edit: I have to ask, is this an actual school assignment or a free online course? Because that "correct" answer cannot be correct if it doesn't even compile :/