Handmade Hero»Forums»Code
17 posts
Hi, I'm bewwys I'm a student at the 42 codingschool . I'm glad to be here. I'm a noob so please take care of me :)
[Question about good practice #1] Cast or not Cast ?
Edited by bewwys on Reason: Initial post
Hello everyone,

first of all I'm not a native english speaker so sorry in case of misspelling.

In my current practice I have the habit to use cast to work directly with the memory. But I heard that some peoples are considering that like a bad practice.

this is an example on the way I use casting:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
void *ft_memchr(const void *ptr, int value, int num)
{
    int i;
    
    i = 0;
    while (i < num)
    {
        if (*((char *)ptr + i) == value)
            return ((void *)((char *)ptr + i));
        i++;
    }
    return (0);
}


Like I said my primary goal is to work with memory in the way I want to. So using cast let me for example doing pointer arithmetic.

I don't understand why we need to be aware of casting when it can be really useful.

Thank you :)

Marc Costa
65 posts
[Question about good practice #1] Cast or not Cast ?
Edited by Marc Costa on
There's nothing wrong with casting memory. Memory is just a bunch of bytes, it's up to you how you interpret them. It gets a little hairy when you use a C++ feature, though: inheritance. C++ has a bunch of casting operators to deal with different types of casting: static_cast, reinterpret_cast, dynamic_cast, etc...

reinterpret_cast is the same as a C-style cast, no checks, no guarantees. A static_cast will have some checks to make sure one type can be converted to the other one.

A dynamic_cast will use RTTI (Run Time Type Information) to safely cast through the inheritance chain (returns NULL if the cast is invalid). For example, a C-style cast will fail when casting between parents in a multiple inheritance situation.

In your example, I would probably ask why don't you pass a const char* ptr instead of a const void*, to avoid the cast inside the function, but there's nothing wrong with it.

As an aside, I tend to use a cast "operator" that makes it more explicit, easier to search for and doesn't break the C-style casting:
1
2
3
4
#define cast(type) (type)

// in code...
float *array = cast(float*) AllocArray(10, sizeof(float));


Mārtiņš Možeiko
2559 posts / 2 projects
[Question about good practice #1] Cast or not Cast ?
Edited by Mārtiņš Možeiko on
I'm not sure I understand question. IMHO the answer is simple - you do the cast when you need cast, and you don't do the cast when you don't need to.

In your example you need a cast. Because you cannot dereference ptr pointer - it points to void type, compiler won't know what to do with void type.
But I would write your code example like this:
1
2
3
4
5
6
7
8
    char* ptr8 = (char*)ptr;
    i = 0;
    while (i < num)
    {
        if (ptr8[i] == value)
            return ptr8 + i;
        i++;
    }

Much simpler to read and understand what's happening. And if you write C instead of C++ then you can simplify first line to this:
1
const char* ptr8 = ptr;

Casts to and from void* are implicit in C.
17 posts
Hi, I'm bewwys I'm a student at the 42 codingschool . I'm glad to be here. I'm a noob so please take care of me :)
[Question about good practice #1] Cast or not Cast ?
Thank you,

that's much clear.
unfortunately I need to respect the function def given by the exercice.

I really like the way you handle the cast with the def macro.

Thank you really much.


:-)



17 posts
Hi, I'm bewwys I'm a student at the 42 codingschool . I'm glad to be here. I'm a noob so please take care of me :)
[Question about good practice #1] Cast or not Cast ?
mmozeiko
I'm not sure I understand question. IMHO the answer is simple - you do the cast when you need cast, and you don't do the cast when you don't need to.

In your example you need a cast. Because you cannot dereference ptr pointer - it points to void type, compiler won't know what to do with void type.
But I would write your code example like this:
1
2
3
4
5
6
7
8
    char* ptr8 = (char*)ptr;
    i = 0;
    while (i < num)
    {
        if (ptr8[i] == value)
            return ptr8 + i;
        i++;
    }

Much simpler to read and understand what's happening. And if you write C instead of C++ then you can simplify first line to this:
1
const char* ptr8 = ptr;

Casts to and from void* are implicit in C.


I know many peoples who tells me don't deal with cast… I don' understand why. Maybe they encountered bad experience with it. ^^


511 posts
[Question about good practice #1] Cast or not Cast ?
bewwys

I know many peoples who tells me don't deal with cast… I don' understand why. Maybe they encountered bad experience with it. ^^




It's because you are circumventing the type system and the safety it brings you. And most of the time there are ways to do what you need without the cast.
101 posts
[Question about good practice #1] Cast or not Cast ?
Wasn't there some sort of undefined behavior related to casting things to "wrong types"?
Mārtiņš Možeiko
2559 posts / 2 projects
[Question about good practice #1] Cast or not Cast ?
Its only undefined if you cast between pointer types with different alignment requirements. So short* -> float* is undefined. And between function pointers vs non-function pointers.
But casting pointer types from and to void* is perfectly legal cast. Also it is legal to cast non-function pointer types to char*.