我需要重写这行代码,需要帮助

时间:2011-04-13 14:29:30

标签: c windows linux

我正在尝试编译下面找到的这段代码。 但是,我在iteminfo_fields,weaponinfo_fields和projectileinfo_fields定义的每一行都有一个错误,说“初始化值必须是常量表达式。”,除了每​​个“{NULL,0,0}”的最后一行 我猜这是来自ITEMINFO_OFS(),WEAPON_OFS(),PROJECTILE_OFS()。

我想了解这三行:

#define WEAPON_OFS(x) (size_t)&(((weaponinfo_t *)0)->x)
#define PROJECTILE_OFS(x) (size_t)&(((projectileinfo_t *)0)->x)
#define ITEMINFO_OFS(x) (size_t)&(((iteminfo_t *)0)->x)

但是,我真的无法理解它们是如何工作的...... 我需要帮助解剖它们。任何人都可以阅读它们并以更简单的形式重写它们吗?

#define WEAPON_OFS(x) (size_t)&(((weaponinfo_t *)0)->x)
#define PROJECTILE_OFS(x) (size_t)&(((projectileinfo_t *)0)->x)
#define ITEMINFO_OFS(x) (size_t)&(((iteminfo_t *)0)->x)

fielddef_t iteminfo_fields[] =
{
{"name", ITEMINFO_OFS(name), FT_STRING},
{"model", ITEMINFO_OFS(model), FT_STRING},
{"modelindex", ITEMINFO_OFS(modelindex), FT_INT},
{"type", ITEMINFO_OFS(type), FT_INT},
{"index", ITEMINFO_OFS(index), FT_INT},
{"respawntime", ITEMINFO_OFS(respawntime), FT_FLOAT},
{"mins", ITEMINFO_OFS(mins), FT_FLOAT|FT_ARRAY, 3},
{"maxs", ITEMINFO_OFS(maxs), FT_FLOAT|FT_ARRAY, 3},
{NULL, 0, 0}
};
//weapon definition
static fielddef_t weaponinfo_fields[] =
{
{"number", WEAPON_OFS(number), FT_INT}, //weapon number
{"name", WEAPON_OFS(name),FT_STRING},   //name of the weapon
{"level", WEAPON_OFS(level), FT_INT},
{"model", WEAPON_OFS(model), T_STRING}, //model of the weapon
{"weaponindex", WEAPON_OFS(weaponindex), FT_INT},//index of weapon in inventory
{"flags", WEAPON_OFS(flags), FT_INT},//special flags
{"projectile", WEAPON_OFS(projectile), FT_STRING},//projectile used by the weapon
{"numprojectiles", WEAPON_OFS(numprojectiles), FT_INT}, //number of projectiles
{"hspread", WEAPON_OFS(hspread), FT_FLOAT},//horizontal spread of projectiles (degrees from middle)
{"vspread", WEAPON_OFS(vspread), FT_FLOAT},//vertical spread of projectiles (degrees from middle)
{"speed", WEAPON_OFS(speed), FT_FLOAT}, //speed of the projectile (0 = instant hit)
{"acceleration", WEAPON_OFS(acceleration), FT_FLOAT},//"acceleration" * time (in seconds) + "speed" = projectile speed
{"recoil", WEAPON_OFS(recoil), FT_FLOAT|FT_ARRAY, 3},//amount of recoil the player gets from the weapon
{"offset", WEAPON_OFS(offset), FT_FLOAT|FT_ARRAY, 3},//projectile start offset relative to eye and view angles
{"angleoffset", WEAPON_OFS(angleoffset), FT_FLOAT|FT_ARRAY, 3},//offset of the shoot angles relative to the view angles
{"extrazvelocity", WEAPON_OFS(extrazvelocity), FT_FLOAT},//extra z velocity the projectile gets
{"ammoamount", WEAPON_OFS(ammoamount), FT_INT}, //ammo amount used per shot
{"ammoindex", WEAPON_OFS(ammoindex), FT_INT},   //index of ammo in inventory
{"activate", WEAPON_OFS(activate), FT_FLOAT},   //time it takes to select the weapon
{"reload", WEAPON_OFS(reload), FT_FLOAT},   //time it takes to reload the weapon
{"spinup", WEAPON_OFS(spinup), FT_FLOAT},   //time it takes before first shot
{"spindown", WEAPON_OFS(spindown), FT_FLOAT},   //time it takes before weapon stops firing
{NULL, 0, 0, 0}
};

//projectile definition
static fielddef_t projectileinfo_fields[] =
{
{"name", PROJECTILE_OFS(name), FT_STRING},//name of the projectile
{"model", WEAPON_OFS(model), FT_STRING},//model of the projectile
{"flags", PROJECTILE_OFS(flags), FT_INT},//special flags
{"gravity", PROJECTILE_OFS(gravity), FT_FLOAT}, //amount of gravity applied to the projectile [0,1]
{"damage", PROJECTILE_OFS(damage), FT_INT},//damage of the projectile
{"radius", PROJECTILE_OFS(radius), FT_FLOAT},//radius of damage
{"visdamage", PROJECTILE_OFS(visdamage), FT_INT},//damage of the projectile to visible entities
{"damagetype", PROJECTILE_OFS(damagetype), FT_INT},//type of damage (combination of the DAMAGETYPE_? flags)
{"healthinc", PROJECTILE_OFS(healthinc), FT_INT},//health increase the owner gets
{"push", PROJECTILE_OFS(push), FT_FLOAT},//amount a player is pushed away from the projectile impact
{"detonation", PROJECTILE_OFS(detonation), FT_FLOAT},//time before projectile explodes after fire pressed
{"bounce", PROJECTILE_OFS(bounce), FT_FLOAT},   //amount the projectile bounces
{"bouncefric", PROJECTILE_OFS(bouncefric), FT_FLOAT}, //amount the bounce decreases per bounce
{"bouncestop", PROJECTILE_OFS(bouncestop), FT_FLOAT},//minimum bounce value before bouncing stops
//recurive projectile definition??
{NULL, 0, 0, 0}
};

注意: 我的情况目前有点复杂。然而, 我不知道编译器的名称。环境是Linux的。 这不是我的代码,但我需要编译它。

2 个答案:

答案 0 :(得分:3)

宏尝试从包含该成员的struct的开头提取命名成员的偏移量。

而不是WEAPON_OFS(name)使用offsetof(weaponinfo_t,name) - 与其他宏类似。

编辑:宏实际上做了什么。

#define WEAPON_OFS(x) (size_t)&(((weaponinfo_t *)0)->x)

这个宏“假装”在地址0处有一个weaponinfo_t结构,并获取此weaponinfo_t结构的特定成员的地址。这将产生从结构位置(0)到成员变量位置(0或更高)作为指针的偏移量。然后将指针强制转换为积分,该积分仍然是从结构的开头到成员变量的开始的距离 - 结构中成员变量的偏移量

显然你的编译器无法解析这个编译时间(完全可以这样做) - 所以你得到一个错误而不是初始化器所需的常量值。

答案 1 :(得分:0)

看起来很有趣的宏从offsetof重新实现<stddef.h>

他们通过要求编译器“假装地址0处有struct foo的实例,该结构中字段bar的地址是什么来工作?”

由于0(也称为NULL指针)永远不会被解引用(该字段永远不会被写入或读取,它只是将其地址与&运算符一起使用),因此这不是未定义的行为。 / p>

由于struct实例本身的地址为0,因此字段的地址等于该字段从结构起始处的偏移量时,编译器提供的任何地址都是等。