Search code examples
cpointersarmdeclarationgame-boy-advance

"Assignment makes pointer from integer without cast" warning isn't consistent across functions


I'm using this header file to create two screen-related functions for the Game Boy Advance. The first function ClearScreenWithColor takes values for red, blue, and green and erases the bitmap screen with that color. The second is supposed to set or clear an undocumented display register that changes how the colors are displayed. Since these are memory-mapped ports, the data must be written to specific memory addresses. The variables Screen and REG_GREENSWAP stand in for the appropriate memory addresses. Here is the code below.

//SCREEN SETTINGS FUNCTIONS
#ifndef SCREENFUNC_H
#define SCREENFUNC_H

#define RGB16(r,g,b) ((r)+(g<<5)+(b<<10))
void ClearScreenWithColor(int red, int green, int blue)
// must be in screen mode 3 or this won't work.
{
    unsigned short* Screen = (unsigned short*)0x6000000;
    // define the pointer variable Screen to contain
    // the memory address 0x06000000.
    int color = RGB16(red,green,blue);
    char x,y;
    
    for (x = 0; x < 240; x++)
    {
        for (y = 0; y < 160; y++)
        {
            Screen[x+y*240] = color;
        }
    }
}

void GreenSwap(short toggle)
{
    unsigned short* REG_GREENSWAP = (unsigned short*)0x04000002;
    
    REG_GREENSWAP = toggle;
}

#endif

When I compile the file, I get the following warning:

C:\gbaprog\gbaprint_test>gcc -S -o gbaprint_test.asm gbaprint_test.c
In file included from C:/gbaprog/lib/lib_header.h:9,
                 from gbaprint_test.c:19:
C:/gbaprog/lib/screenfunc.h: In function `GreenSwap':
C:/gbaprog/lib/screenfunc.h:28: warning: assignment makes pointer from integer without a cast

That being said, the function ClearScreenWithColor doesn't produce this error message even though it uses the same syntax to assign the variable Screen. Why is the function GreenSwap different and what is different about my variable declaration?


Solution

  • The problem is on this line:

    REG_GREENSWAP = toggle;
    

    toggle has type short while REG_GREENSWAP has type short *, so (as the error message says) you're assigning an integer value to a pointer without a cast. This is also overwriting the value that REG_GREENSWAP was initialized with.

    Presumably, what you actually want to do is to dereference REG_GREENSWAP and write to the memory location it points to.

    *REG_GREENSWAP = toggle;
    

    There's no error with Screen[x+y*240] = color; because array indexing implicitly dereferneces a pointer.

    On a side note, it's not a good idea to have a function's implementation in a header file. If that header is included in more that one source file, the function will be defined in each object file and when you attempt to link them you'll get a multiple definition error.

    The header should only include declarations for your functions while the implementation should be in exactly one source file.