c - Jeg har brug for at omskrive denne linje kode og har brug for hjælp

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at kompilere dette stykke kode, der findes nedenfor.
Imidlertid fik jeg en fejl, der siger 'Initialiseringsværdi skal være konstant udtryk'. På hver linje af iteminfo\_fields, weaponinfo\_fields og projectileinfo\_fields definitioner, undtagen i den sidste linje i hver '{NULL, 0, 0}'
Jeg gætter, det er fra ITEMINFO\_OFS (), WEAPON\_OFS (), PROJECTILE\_OFS ().


Jeg forsøger at forstå disse tre linjer:


#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)


Men jeg kan virkelig ikke forstå, hvordan de arbejder ... ???
Jeg har brug for hjælp dissekere dem. Kan nogen læse dem og omskrive dem i en enklere 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}
};


Bemærk:
Min situation er lidt kompliceret i øjeblikket. Imidlertid,
Jeg kender ikke navnet på kompilatoren. Miljøet er Linux tho.
Det er ikke min kode, men jeg skal have den sammen.

Bedste reference


Makroerne forsøger at udtrække offset for et navngivet medlem fra starten af ​​strukturen, der indeholder det pågældende medlem.


I stedet for WEAPON\_OFS(name) brug offsetof(weaponinfo\_t,name) - og ligner de andre makroer.


EDIT: Hvad makroerne rent faktisk gør.


#define WEAPON\_OFS(x) (size\_t)&(((weaponinfo\_t *)0)->x)


Denne makro 'foregiver' der er en weaponinfo\_t struktur på adresse 0, og tager adressen til et bestemt medlem af denne weaponinfo\_t struct. Dette giver forskydningen fra strukturernes placering (0) til medlemsvariablernes placering (0 eller højere) som en pointer. Pegeren kastes derefter til en integreret del, som stadig er afstanden fra starten af ​​strukturen til begyndelsen af ​​medlemsvariabelen - forskydning af medlemsvariablen i strukturen.


Tilsyneladende kan din compiler ikke løse denne compiletime (som det er helt muligt at gøre selvom) - så du får en fejl i stedet for den konstante værdi, der er nødvendig for dine initialisatorer.

Andre referencer 1


De spændende udseende makroer genudfører offsetof, fra <stddef.h>.


De arbejder ved at spørge kompilatoren 'foregive at der er en forekomst af struct foo ved adresse 0, hvad er adressen til feltet bar i den struktur?'


Da 0'en (også kendt som en NULL-pointer) aldrig genberegnes (feltet er aldrig skrevet til eller læses, det har bare sin adresse taget med operatøren &, dette er ikke udefineret adfærd.


Da adressen til selve struct -eksemplet er 0, kommer uanset adressen til kompilatoren, da feltets adresse er så lig med feltet, der er forskudt fra strukturens start.