diff --git a/include/decl.h b/include/decl.h index d78e7cbaa..dba448c71 100644 --- a/include/decl.h +++ b/include/decl.h @@ -468,7 +468,6 @@ struct instance_globals_i { boolean in_mk_themerooms; /* new */ - struct obj invalid_obj; boolean havestate; unsigned long magic; /* validate that structure layout is preserved */ @@ -1149,6 +1148,8 @@ struct const_globals { extern const struct const_globals cg; +extern struct obj hands_obj; + #endif /* DECL_H */ diff --git a/src/apply.c b/src/apply.c index 1d89a23ca..32e7a4faf 100644 --- a/src/apply.c +++ b/src/apply.c @@ -2564,7 +2564,7 @@ use_grease(struct obj *obj) consume_obj_charge(obj, TRUE); oldglib = (int) (Glib & TIMEOUT); - if (otmp != &gi.invalid_obj) { + if (otmp != &hands_obj) { You("cover %s with a thick layer of grease.", yname(otmp)); otmp->greased = 1; if (obj->cursed && !nohands(gy.youmonst.data)) { diff --git a/src/decl.c b/src/decl.c index 810f4045e..9a949f9bc 100644 --- a/src/decl.c +++ b/src/decl.c @@ -440,7 +440,6 @@ const struct instance_globals_i g_init_i = { UNDEFINED_PTR, /* id_map */ /* sp_lev.c */ FALSE, /* in_mk_themerooms */ - DUMMY, /* invalid_obj */ TRUE, /* havestate*/ IVMAGIC /* i_magic to validate that structure layout has been preserved */ @@ -1059,6 +1058,8 @@ decl_globals_init(void) gu.urace = urace_init_data; } +/* fields in 'hands_obj' don't matter, just its distinct address */ +struct obj hands_obj = DUMMY; /* gcc 12.2's static analyzer thinks that some fields of gc.context.victual are uninitialized when compiling 'bite(eat.c)' but that's impossible; diff --git a/src/eat.c b/src/eat.c index 841b2598d..a400dbd9e 100644 --- a/src/eat.c +++ b/src/eat.c @@ -2719,8 +2719,8 @@ doeat(void) } } - /* from floorfood(), &gi.invalid_obj means iron bars at current spot */ - if (otmp == &gi.invalid_obj) { + /* from floorfood(), &hands_obj means iron bars at current spot */ + if (otmp == &hands_obj) { /* hero in metallivore form is eating [diggable] iron bars at current location so skip the other assorted checks; operates as if digging rather than via the eat occupation */ @@ -3507,7 +3507,7 @@ floorfood( c = yn_function(qbuf, ynqchars, 'n', TRUE); } if (c == 'y') - return &gi.invalid_obj; + return &hands_obj; else if (c == 'q') return (struct obj *) 0; ++getobj_else; diff --git a/src/engrave.c b/src/engrave.c index 1811db586..543333ecc 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -532,7 +532,7 @@ doengrave(void) if (!otmp) /* otmp == cg.zeroobj if fingers */ return ECMD_CANCEL; - if (otmp == &gi.invalid_obj) { + if (otmp == &hands_obj) { Strcat(strcpy(fbuf, "your "), body_part(FINGERTIP)); writer = fbuf; } else { @@ -563,7 +563,7 @@ doengrave(void) return ECMD_OK; } if (IS_GRAVE(levl[u.ux][u.uy].typ)) { - if (otmp == &gi.invalid_obj) { /* using only finger */ + if (otmp == &hands_obj) { /* using only finger */ You("would only make a small smudge on the %s.", surface(u.ux, u.uy)); return ECMD_OK; @@ -1024,7 +1024,7 @@ doengrave(void) } /* Tell adventurer what is going on */ - if (otmp != &gi.invalid_obj) + if (otmp != &hands_obj) You("%s the %s with %s.", everb, eloc, doname(otmp)); else You("%s the %s with your %s.", everb, eloc, body_part(FINGERTIP)); @@ -1131,7 +1131,7 @@ engrave(void) } /* Stylus might have been taken out of inventory and destroyed somehow. * Not safe to dereference stylus until after this. */ - if (gc.context.engraving.stylus == &gi.invalid_obj) { /* bare finger */ + if (gc.context.engraving.stylus == &hands_obj) { /* bare finger */ stylus = (struct obj *) 0; } else { for (stylus = gi.invent; stylus; stylus = stylus->nobj) { diff --git a/src/files.c b/src/files.c index 6dedea56b..783ea1eee 100644 --- a/src/files.c +++ b/src/files.c @@ -3880,7 +3880,7 @@ fopen_wizkit_file(void) static void wizkit_addinv(struct obj *obj) { - if (!obj || obj == &gi.invalid_obj) + if (!obj || obj == &hands_obj) return; /* subset of starting inventory pre-ID */ @@ -3912,7 +3912,7 @@ proc_wizkit_line(char *buf) otmp = readobjnam(buf, (struct obj *) 0); if (otmp) { - if (otmp != &gi.invalid_obj) + if (otmp != &hands_obj) wizkit_addinv(otmp); } else { /* .60 limits output line width to 79 chars */ diff --git a/src/fountain.c b/src/fountain.c index 398212085..abc8d968c 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -391,7 +391,7 @@ void dipfountain(struct obj *obj) { int er = ER_NOTHING; - boolean is_hands = (obj == &gi.invalid_obj); + boolean is_hands = (obj == &hands_obj); if (Levitation) { floating_above("fountain"); @@ -705,7 +705,7 @@ dipsink(struct obj *obj) { boolean try_call = FALSE, not_looted_yet = (levl[u.ux][u.uy].looted & S_LRING) == 0, - is_hands = (obj == &gi.invalid_obj || (uarmg && obj == uarmg)); + is_hands = (obj == &hands_obj || (uarmg && obj == uarmg)); if (!rn2(not_looted_yet ? 25 : 15)) { /* can't rely on using sink for unlimited scroll blanking; however, diff --git a/src/invent.c b/src/invent.c index a6bc63f55..9d2431898 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1527,13 +1527,13 @@ any_obj_ok(struct obj *obj) * getobj returns: * struct obj *xxx: object to do something with. * (struct obj *) 0 error return: no object. - * &gi.invalid_obj explicitly no object (as in w-). + * &hands_obj explicitly no object (as in w-). * The obj_ok callback should not have side effects (apart from * abnormal-behavior things like impossible calls); it can be called multiple * times on the same object during the execution of this function. * Callbacks' argument is either a valid object pointer or a null pointer, * which represents the validity of doing that action on HANDS_SYM. getobj - * won't call it with &gi.invalid_obj, so its behavior can be undefined in that + * won't call it with &hands_obj, so its behavior can be undefined in that * case. */ struct obj * @@ -1579,7 +1579,7 @@ getobj( /* check whether the hands/self choice is suitable */ v = (*obj_ok)((struct obj *) 0); if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY) - otmp = &gi.invalid_obj; + otmp = &hands_obj; } else { /* there could be more than one match if key is '#'; take first one which passes the obj_ok callback */ @@ -1742,7 +1742,7 @@ getobj( if (ilet == HANDS_SYM) { /* '-' */ if (!allownone) mime_action(word); - return (allownone ? &gi.invalid_obj : (struct obj *) 0); + return (allownone ? &hands_obj : (struct obj *) 0); } redo_menu: /* since gold is now kept in inventory, we need to do processing for @@ -1778,7 +1778,7 @@ getobj( continue; } if (ilet == HANDS_SYM) - return &gi.invalid_obj; + return &hands_obj; if (ilet == '\033') { if (flags.verbose) pline1(Never_mind); diff --git a/src/mkobj.c b/src/mkobj.c index 36a43e0e9..3c1d21ad9 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2631,6 +2631,10 @@ dealloc_obj(struct obj *obj) panic("dealloc_obj with nobj"); if (obj->cobj) panic("dealloc_obj with cobj"); + if (obj == &hands_obj) { + impossible("dealloc_obj with hands_obj"); + return; + } /* free up any timers attached to the object */ if (obj->timed) diff --git a/src/muse.c b/src/muse.c index 41d497625..b5dd3ff94 100644 --- a/src/muse.c +++ b/src/muse.c @@ -2886,7 +2886,7 @@ munslime(struct monst *mon, boolean by_you) } } if (t && t->ttyp == FIRE_TRAP) - return muse_unslime(mon, &gi.invalid_obj, t, by_you); + return muse_unslime(mon, &hands_obj, t, by_you); } /* MUSE */ diff --git a/src/objnam.c b/src/objnam.c index d1f3f9882..e5c80e489 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -3266,7 +3266,7 @@ wizterrainwish(struct _readobjnam_data *d) (trap != MAGIC_PORTAL) ? "" : " to nowhere"); } else pline("Creation of %s failed.", an(tname)); - return &gi.invalid_obj; + return &hands_obj; } /* furniture and terrain (use at your own risk; can clobber stairs @@ -3540,7 +3540,7 @@ wizterrainwish(struct _readobjnam_data *d) } if (madeterrain || badterrain) { /* cast 'const' away; caller won't modify this */ - return &gi.invalid_obj; + return &hands_obj; } return (struct obj *) 0; @@ -4495,7 +4495,7 @@ readobjnam_postparse3(struct _readobjnam_data *d) * Return something wished for. Specifying a null pointer for * the user request string results in a random object. Otherwise, * if asking explicitly for "nothing" (or "nil") return no_wish; - * if not an object return &gi.invalid_obj; if an error (no matching object), + * if not an object return &hands_obj; if an error (no matching object), * return null. */ struct obj * @@ -4960,7 +4960,7 @@ readobjnam(char *bp, struct obj *no_wish) || (d.otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) { artifact_exists(d.otmp, safe_oname(d.otmp), FALSE, ONAME_NO_FLAGS); obfree(d.otmp, (struct obj *) 0); - d.otmp = &gi.invalid_obj; + d.otmp = &hands_obj; pline("For a moment, you feel %s in your %s, but it disappears!", something, makeplural(body_part(HAND))); return d.otmp; diff --git a/src/potion.c b/src/potion.c index 13bb07085..fab7286e6 100644 --- a/src/potion.c +++ b/src/potion.c @@ -2246,7 +2246,7 @@ dodip(void) if (inaccessible_equipment(obj, "dip", FALSE)) return ECMD_OK; - is_hands = (obj == &gi.invalid_obj); + is_hands = (obj == &hands_obj); shortestname = (is_hands || is_plural(obj) || pair_of(obj)) ? "them" : "it"; drink_ok_extra = 0; @@ -2381,7 +2381,7 @@ potion_dip(struct obj *obj, struct obj *potion) pline("That is a potion bottle, not a Klein bottle!"); return ECMD_OK; } - if (obj == &gi.invalid_obj) { + if (obj == &hands_obj) { You("can't fit your %s into the mouth of the bottle!", body_part(HAND)); return ECMD_OK; diff --git a/src/weapon.c b/src/weapon.c index b2bf35826..0dc32d81f 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -509,7 +509,7 @@ select_rwep(struct monst *mtmp) char mlet = mtmp->data->mlet; - gp.propellor = &gi.invalid_obj; + gp.propellor = &hands_obj; Oselect(EGG); /* cockatrice egg */ if (mlet == S_KOP) /* pies are first choice for Kops */ Oselect(CREAM_PIE); @@ -568,7 +568,7 @@ select_rwep(struct monst *mtmp) } /* KMH -- This belongs here so darts will work */ - gp.propellor = &gi.invalid_obj; + gp.propellor = &hands_obj; prop = objects[rwep[i]].oc_skill; if (prop < 0) { @@ -593,7 +593,7 @@ select_rwep(struct monst *mtmp) gp.propellor = 0; } /* propellor = obj, propellor to use - * propellor = &gi.invalid_obj, doesn't need a propellor + * propellor = &hands_obj, doesn't need a propellor * propellor = 0, needed one and didn't have one */ if (gp.propellor != 0) { @@ -788,7 +788,7 @@ mon_wield_item(struct monst *mon) mon_nam(mon)); return 0; } - if (obj && obj != &gi.invalid_obj) { + if (obj && obj != &hands_obj) { struct obj *mw_tmp = MON_WEP(mon); if (mw_tmp && mw_tmp->otyp == obj->otyp) { diff --git a/src/wield.c b/src/wield.c index 351dd3f1b..36fa73636 100644 --- a/src/wield.c +++ b/src/wield.c @@ -384,7 +384,7 @@ dowield(void) } /* Handle no object, or object in other slot */ - if (wep == &gi.invalid_obj) { + if (wep == &hands_obj) { wep = (struct obj *) 0; } else if (wep == uswapwep) { return doswapweapon(); @@ -516,7 +516,7 @@ doquiver_core(const char *verb) /* "ready" or "fire" */ if (!newquiver) { /* Cancelled */ return ECMD_CANCEL; - } else if (newquiver == &gi.invalid_obj) { /* no object */ + } else if (newquiver == &hands_obj) { /* no object */ /* Explicitly nothing */ if (uquiver) { You("now have no ammunition readied."); diff --git a/src/zap.c b/src/zap.c index d3c4f2923..380e2c9c2 100644 --- a/src/zap.c +++ b/src/zap.c @@ -5981,7 +5981,7 @@ makewish(void) } /* * Note: if they wished for and got a non-object successfully, - * otmp == &gi.invalid_obj. That includes an artifact which has been + * otmp == &hands_obj. That includes an artifact which has been * denied. Wishing for "nothing" requires a separate value to remain * distinct. */ @@ -6000,7 +6000,7 @@ makewish(void) to retain wishless conduct */ livelog_printf(LL_WISH, "declined to make a wish"); return; - } else if (otmp == &gi.invalid_obj) { + } else if (otmp == &hands_obj) { /* wizard mode terrain wish: skip livelogging, etc */ return; }