Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer Arithmetic for mmap

recently I was attempting to adapt someone's mmap code and came across the following error. (I am actually a bit dubious about their code now as it looks like they are doing something unnecessary - attempting to use MAP_FIXED with their own page aligned memory. The manpage suggests calling mmap with NULL as the addr argument should do this on Linux. ) So I think I will at least test calling mmap with a NULL address. However I don't quite understand the error gcc is throwing up at me when I changed it. Their code works ok while I get lvalue required as left operand of assignment.

Essentially they were doing the following:

    uint8_t * ptr = (uint8_t *)mem;
    if ((uint32_t)ptr % PAGE_SIZE)
    {
        ptr += PAGE_SIZE - ((uint32_t)ptr % PAGE_SIZE);
    }

Where mem is a void * to some malloc'd memory.

I am trying more or less the same with typecasts:

    if ((uint32_t)mem % PAGE_SIZE)
    {   
        (uint8_t *)mem += PAGE_SIZE - ((uint32_t)mem % PAGE_SIZE); /* ERROR */
    }

So I thought I was being smart and removing a variable which wasn't in my mind required. Could someone enlighten me on why my typecasting is off? Cheers.

like image 863
Alan Avatar asked Jul 08 '12 13:07

Alan


1 Answers

The mistake you're making is:

(uint8_t *)mem += /* Anything.  */

You simply cannot assign to the result of a cast. The result of a cast is not the same value as the original expression.

Think about how weird it would be to do:

(int) some_char_variable = 9999;

I had trouble for the same reason once.

Use a temp, and write back the result, OR, as R.. says in their comment:

mem = (void *) ( ( (uint8_t *) mem) + SOME_EXPRESSION );
like image 163
ArjunShankar Avatar answered Sep 29 '22 20:09

ArjunShankar