Handmade Hero » Forums » Code » [Question about good practice #1] Cast or not Cast ?
bewwys
8 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 :)

#15586 [Question about good practice #1] Cast or not Cast ?
1 month ago Edited by bewwys on June 19, 2018, 12:08 p.m. 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 :)

marcc
Marc Costa
28 posts
#15589 [Question about good practice #1] Cast or not Cast ?
1 month ago Edited by Marc Costa on June 19, 2018, 4:40 p.m.

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));


mmozeiko
Mārtiņš Možeiko
1720 posts / 1 project
#15590 [Question about good practice #1] Cast or not Cast ?
1 month ago Edited by Mārtiņš Možeiko on June 19, 2018, 4:47 p.m.

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.
bewwys
8 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 :)

#15592 [Question about good practice #1] Cast or not Cast ?
1 month ago

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.


:-)



bewwys
8 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 :)

#15593 [Question about good practice #1] Cast or not Cast ?
1 month ago

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. ^^


ratchetfreak
377 posts
#15594 [Question about good practice #1] Cast or not Cast ?
1 month ago

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.
pragmatic_hero
101 posts
#15597 [Question about good practice #1] Cast or not Cast ?
1 month ago

Wasn't there some sort of undefined behavior related to casting things to "wrong types"?
mmozeiko
Mārtiņš Možeiko
1720 posts / 1 project
#15604 [Question about good practice #1] Cast or not Cast ?
1 month ago

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*.