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
memchrfunctionSynopsis
#include <string.h> void *memchr(const void *s, int c, size_t n);Description
The
memchrfunction 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
memchrfunction 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