[PATCH 7/7] qsort.3: Fix casts

Alejandro Colomar
2020-09-05T15:17:19Z

`p1` (and `p2` too) is `const void *` and it comes from a
`const char **` (for legacy reasons, argv is not `const` but should be
treated as if it were). That means, the ultimate `char` is `const`:
"a pointer to a pointer to a const char".

Let's see what is going on before the fix first, and then the fix.

Before the fix:

`(char *const *)` (I removed the space on purpose) casts `p1` to be
"a pointer to a const pointer to a non-const char". That's clearly
not what it originally was.

Then we dereference, ending with a `char *const`, which is
"a const pointer to a non-const char". But given that the pointer value
is passed to a function, `const` doesn't make sense there, because the
function will already take a copy of it, so it is impossible to modify
the pointer itself.

The fix:

`(const char **)` The only thing that is const is the ultimate `char`,
which is the only thing that matters, because it is the only thing
strcmp(3) has access to (everything else, i.e. the pointers, are
copies).

Then, after the dereference we end up with `const char *`, the type of
argv (more or less, as previously noted), which is also the type of the
arguments to strcmp(3).

Signed-off-by: Alejandro Colomar <colomar.6.4.3@gmail.com>
---
man3/qsort.3 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/man3/qsort.3 b/man3/qsort.3
index e1af43cf0..24f0b6c92 100644
--- a/man3/qsort.3
+++ b/man3/qsort.3
@@ -137,7 +137,7 @@ cmpstringp(const void *p1, const void *p2)
pointers to char", but strcmp(3) arguments are "pointers
to char", hence the following cast plus dereference */

- return strcmp(* (char * const *) p1, * (char * const *) p2);
+ return strcmp(*(const char **) p1, *(const char **) p2);
}

int
--
2.28.0