"Assignment makes pointer from integer without cast" 函数之间的警告不一致
"Assignment makes pointer from integer without cast" warning isn't consistent across functions
我正在使用此头文件为 Game Boy Advance 创建两个与屏幕相关的函数。第一个函数 ClearScreenWithColor
获取红色、蓝色和绿色的值,并用该颜色擦除位图屏幕。第二个应该设置或清除一个未记录的显示寄存器,该寄存器会更改颜色的显示方式。由于这些是内存映射端口,数据必须写入特定的内存地址。变量 Screen
和 REG_GREENSWAP
代表适当的内存地址。这是下面的代码。
//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
当我编译文件时,我收到以下警告:
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
也就是说,函数 ClearScreenWithColor
不会产生此错误消息,即使它使用相同的语法来分配变量 Screen
。为什么函数 GreenSwap
不同,我的变量声明有何不同?
问题出在这一行:
REG_GREENSWAP = toggle;
toggle
的类型为 short
而 REG_GREENSWAP
的类型为 short *
,因此(如错误消息所述)您将一个整数值分配给一个指针而不一个演员。这也覆盖了 REG_GREENSWAP
初始化的值。
据推测,您真正想要做的是取消引用 REG_GREENSWAP
并写入它指向的内存位置。
*REG_GREENSWAP = toggle;
Screen[x+y*240] = color;
没有错误,因为数组索引隐式取消引用指针。
附带说明一下,在 header 文件中实现函数并不是一个好主意。如果 header 包含在多个源文件中,则该函数将在每个 object 文件中定义,当您尝试 link 它们时,您将收到多重定义错误。
header 应该只包含函数的 声明 ,而实现应该恰好在一个源文件中。
我正在使用此头文件为 Game Boy Advance 创建两个与屏幕相关的函数。第一个函数 ClearScreenWithColor
获取红色、蓝色和绿色的值,并用该颜色擦除位图屏幕。第二个应该设置或清除一个未记录的显示寄存器,该寄存器会更改颜色的显示方式。由于这些是内存映射端口,数据必须写入特定的内存地址。变量 Screen
和 REG_GREENSWAP
代表适当的内存地址。这是下面的代码。
//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
当我编译文件时,我收到以下警告:
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
也就是说,函数 ClearScreenWithColor
不会产生此错误消息,即使它使用相同的语法来分配变量 Screen
。为什么函数 GreenSwap
不同,我的变量声明有何不同?
问题出在这一行:
REG_GREENSWAP = toggle;
toggle
的类型为 short
而 REG_GREENSWAP
的类型为 short *
,因此(如错误消息所述)您将一个整数值分配给一个指针而不一个演员。这也覆盖了 REG_GREENSWAP
初始化的值。
据推测,您真正想要做的是取消引用 REG_GREENSWAP
并写入它指向的内存位置。
*REG_GREENSWAP = toggle;
Screen[x+y*240] = color;
没有错误,因为数组索引隐式取消引用指针。
附带说明一下,在 header 文件中实现函数并不是一个好主意。如果 header 包含在多个源文件中,则该函数将在每个 object 文件中定义,当您尝试 link 它们时,您将收到多重定义错误。
header 应该只包含函数的 声明 ,而实现应该恰好在一个源文件中。