我需要重写这一行代码,并且需要帮助 [英] I need to rewrite this line of code, and need help
问题描述
我正在尝试编译下面的这段代码.
但是,在iteminfo_fields,weaponinfo_fields和projectileinfo_fields定义的每一行上,除了每个"{NULL,0,0}"的最后一行之外,我都收到一条错误消息,指出初始化值必须为常数表达式."
我猜它来自ITEMINFO_OFS(),WEAPON_OFS(),PROJECTILE_OFS().
我正在尝试理解以下三行内容:
Hi,
I am trying to compile this piece of code found below.
However, I got an error saying "Initialization value must be constant expression."on every line of iteminfo_fields, weaponinfo_fields and projectileinfo_fields definitions, except at the last line of each "{NULL, 0, 0}"
I am guessing it is from ITEMINFO_OFS(), WEAPON_OFS(), PROJECTILE_OFS().
I am trying to understand these three lines:
#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)
但是,我真的不明白它们是如何工作的... ???
我需要剖析它们的帮助.任何人都可以阅读它们并以更简单的形式重写它们吗?
But, I really cannot understand how they work...???
I need help dissecting them. Can anyone read them and rewrite them in a simpler form?
#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.
这不是我的代码,但我需要对其进行编译.
Note:
My situation is a bit complicated at the moment. However,
I do not know the name of the compiler. The environment is Linux tho.
It is not my code, but I need to have it compile.
推荐答案
这3个宏计算结构中给定数据成员的字段偏移量. > 例如:
The 3 macros compute the field offset of a given data member within a structure.
For example:
struct MY_STRUCT
{
//a is an int, so it takes 4 bytes
int a;
//b is a float, so it takes 4 bytes
float b;
//c is a char, so it takes 1 byte
char c;
...
};
void ComputeFieldOffsets()
{
//to compute the field offset for each data member
//you can do something like that:
//declare a variable from the structure
MY_STRUCT myStruct;
//get the address of the struct
void* pBase = (void*)&myStruct;
//get the address of field a
void* pA =(void*)&myStruct.a;
//get the offset of a
size_t offestA = (size_t)pA - (size_t)pBase;
//Since a is the first field in the struct, offsetA equals 0
//
//get the address of field b
void* pB =(void*)&myStruct.b;
//get the offset of b
size_t offestB = (size_t)pB - (size_t)pBase;
//Since b is declared just after a, and a is 4 bytes, offsetB equals 4
//actually it can be different, especially if you are running on a 64 bits system
//because the compiler decides how to store the data for optimizations
//
//get the address of field c
void* pC =(void*)&myStruct.c;
//get the offset of c
size_t offestC = (size_t)pC - (size_t)pBase;
//Since c is declared just after b, and b is 4 bytes, offsetC equals 8
//
//and so on
...
}
编写宏的人想计算这些偏移量.但是,他没有声明结构体并获取其地址,而是使用了NULL指针(宏定义内的0
).
与我的示例相比,就好像您将pBase
指针替换为NULL指针一样:
The guy who wrote the macro wanted to compute these offsets. But instead of declaring a struct and taking its address, he used a NULL pointer (the 0
inside the macro definition).
Compared to my example, it is as if you replaced pBase
pointer by a NULL pointer:
size_t offestA = (size_t)pA - (size_t)pBase;
//or
size_t offestA = (size_t)(&myStruct.a) - (size_t)pBase;
//or
size_t offestA = (size_t)(&((MY_STRUCT*)pBase)->a) - (size_t)pBase;
//and if you replace pBase by 0
size_t offestA = (size_t)(&((MY_STRUCT*)0)->a) - (size_t)0;
//or
size_t offestA = (size_t)(&((MY_STRUCT*)0)->a);
这个家伙想编写一个函数,该函数可以返回任何字段名称的字段偏移量,因此他只是将字段名称设为宏的参数:x
.
总结一下:
-WEAPON_OFS(number)
返回weaponinfo_t
结构
中number
的字段偏移量
-PROJECTILE_OFS(model)
返回projectileinfo_t
结构
中model
的字段偏移量
-等等...
他可能有充分的理由对这些东西进行编码,但是我不建议您养成这种习惯……这是一种肮脏的编程".
我的意见是,他这样做是为了使他的数据文件更灵活地进行更改:他可能会存储所有成员及其说明,以便即使文件格式发生更改也可以重新加载它们...
And the guy wanted to write a function which could return the field offset for any field name, so he just made the field name a parameter of the macro: x
.
To sumerize:
- WEAPON_OFS(number)
returns the field offset of number
within the weaponinfo_t
struct
- PROJECTILE_OFS(model)
returns the field offset of model
within the projectileinfo_t
struct
- and so on...
He probably had a good reason to code these things, but I wouldn''t recommand to take such habits... This is kind of "dirty programming".
My opinion is he made this to make his data file more flexible to changes: he probably stores all members with their description, so they can be reloaded even if the file format changes...
C标准提供了offsetof
,您应该使用它代替NULL-> ...
The C standard provides offsetof
that you should use instead of the NULL->...
对我来说,就像它根据值的类型定义字段偏移量一样由指定的字段名称表示.
Looks to me like it''s defining a field offset based on the type of value that''s represented by the specified field name.
这篇关于我需要重写这一行代码,并且需要帮助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!