我需要重写这一行代码,并且需要帮助 [英] I need to rewrite this line of code, and need help

查看:77
本文介绍了我需要重写这一行代码,并且需要帮助的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我正在尝试编译下面的这段代码.
但是,在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆