Page 1 of 1

My personal C pointer casting mess

Posted: Fri Apr 03, 2009 1:54 am
by Andy1988
Hi all,
I can say for myself that I'm quite good at programming, but when writing an operating system you sometimes have to program in a different way than programming somewhere in the userspace where all the dirty work is done for you with libs and the operating system itself.

I've been coding my kmalloc() last night and I did some very ugly pointer casting mess, I think.

Only one example:
I've got the following global, static variable in my file which hold the current end of my heap, to see wether a the heap needs a new frame mapped into the address space or not:

Code: Select all

static uint8_t* kheap_current_end = (void*)KHEAP_START;
I also have a struct, which defines the begining of a memory block in the heap (mem_info).
If I want to edit this on a specific location, I need to do such a cast:

Code: Select all

struct mem_info *newBlock = (struct mem_info *)(kheap_start);
This would give me the beginning of the linked list for managing my memory blocks in the heap.

Now I allocated some bytes, splitted up the linked list, created a new item for it and I want to know if I need to allocate a new frame and map it to the end of the heap to store the new linked list item.
I need to do such an ugly casting mess to check this:

Code: Select all

if((uint32_t)newBlock + sizeof(struct mem_info) > (uint32_t)kheap_current_end) expandKheap();
This just doesn't look right. But I can't add anything I want to my pointers or even compare them. So I have to cast them to a normal integer.
Is this really neccessary?

Re: My personal C pointer casting mess

Posted: Fri Apr 03, 2009 9:49 am
by jgraef
This should also work:

Code: Select all

if (newBlock + 1 > kheap_current_end) expandKheap();
Since newBlock is a pointer to a struct mem_info +1 will increment the pointer by sizeof(struct mem_info) bytes.
So you still have pointers of both sides of the >.
I'm not sure, but maybe C will moan about the different pointer types. In this case just cast to void*

Code: Select all

if ((void*)(newBlock + 1) > (void*)kheap_current_end) expandKheap();
BTW: Why is kheap_current_end uint8_t* and not void*? Not would it save one void* cast, also I see no reason for kheap_current_end to be uint8_t*.

Re: My personal C pointer casting mess

Posted: Sat Apr 04, 2009 12:04 pm
by Andy1988
jgraef wrote: BTW: Why is kheap_current_end uint8_t* and not void*? Not would it save one void* cast, also I see no reason for kheap_current_end to be uint8_t*.
Yes.. I copy & pasted it from my sourcefile and edited it afterwards.

Now it is a void pointer.

Re: My personal C pointer casting mess

Posted: Sat Apr 04, 2009 1:21 pm
by whowhatwhere
*ahem* void pointer arithmetic. bad,

Re: My personal C pointer casting mess

Posted: Sat Apr 04, 2009 1:26 pm
by Andy1988
Yes, I know...

But I don't know which type would be appropriate to this.
Perhaps uint8_t would be better. I want to address every single byte in my address space. With uint8_t I could do my pointer arithmetic easily.

Re: My personal C pointer casting mess

Posted: Sat Apr 04, 2009 4:36 pm
by pcmattman
You could cast the void pointer to a uint8_t pointer when you need byte access.