I'm working on a school project in which I need to reproduce many of the C library functions. I'm just struggling with one specific aspect of it.
If you look at the man page for memchr
you will see that it takes a const void *
as input and returns a plain void *
. I would assume that somewhere in the function they are casting from const
to non const
for the return variable.
However, when I do this (clang -Weverything +Werror
) it won't compile. It works without the -Weverything
tag but I would prefer to use it if possible anyway.
Is there any "correct" way to do this?
Const casts are only available in C++.
The statement int* c = const_cast<int>(b) returns a pointer c that refers to a without the const qualification of a . This process of using const_cast to remove the const qualification of an object is called casting away constness.
const_cast is safe only if you're casting a variable that was originally non- const . For example, if you have a function that takes a parameter of a const char * , and you pass in a modifiable char * , it's safe to const_cast that parameter back to a char * and modify it.
The whole purpose of const is to prevent you from modifying something, that's why your code generates an error. Adding in const_cast is basically telling the compiler to shut up, that you know what you're doing.
As you correctly noted, some C library functions must cast their const pointer argument to remove the const
qualifier for the return value: memchr
, strchr
, strstr
etc. Other standard functions store a pointer to the end of the parsed string into a char **
, although it points into the array to which they were passed a const char *
: strtol
, strod`...
If your compiler is anal about this and produces warnings, try casting to uintptr_t
before casting to unsigned char *
. You can also use a union
with both pointer types.
The C Standard specifies memcpy
this way:
7.24.5.1 The
memchr
functionSynopsis
#include <string.h> void *memchr(const void *s, int c, size_t n);
Description
The
memchr
function locates the first occurrence ofc
(converted to anunsigned char
) in the initial n characters (each interpreted asunsigned char
) of the object pointed to bys
. The implementation shall behave as if it reads the characters sequentially and stops as soon as a matching character is found.Returns
The
memchr
function returns a pointer to the located character, or a null pointer if the character does not occur in the object.
If you cannot use other types, you may get away with a cast as size_t
to suppress the compiler warning, here is a possible implementation:
void *my_memchr(const void *ptr, int c, size_t num) {
const unsigned char *cptr = ptr;
while (num-- > 0) {
if (*cptr++ == (unsigned char)c) {
/* const pointer is cast first as size_t to avoid a compiler warning.
* a more appropriate type for this intermediary cast would be uintptr_t,
* but this type is not allowed here.
*/
return (void *)(size_t)(cptr - 1);
}
}
return NULL;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With