I found the following macro in the source code of Perl:
#define GvGP(gv) (0 (gv)->sv_u.svu_gp)
where sv_u.svu_gp
is declared as:
GP* svu_gp
in a union sv_u
.
I can't find any definition of GP
. However I am more confused about what 0 plus a pointer means. Could anyone enlighten me please?
CodePudding user response:
I guess it is used to make it an R-value, what makes it read-only in practice.
Example: One can write
x = 1;
but this will not work:
0 x = 1;
Edit
Thanks to Dave Mitchell for pointing a related commit in PERL repository.
add GvCV_set() and GvGP_set() macros.
and make GvCV() and GvGP() rvalue-only. ...
@@ -52,7 57,8 @@ struct gp {
# define GvNAME_get(gv) ({ assert(GvNAME_HEK(gv)); (char *)HEK_KEY(GvNAME_HEK(gv)); })
# define GvNAMELEN_get(gv) ({ assert(GvNAME_HEK(gv)); HEK_LEN(GvNAME_HEK(gv)); })
#else
-# define GvGP(gv) ((gv)->sv_u.svu_gp)
# define GvGP(gv) (0 (gv)->sv_u.svu_gp)
# define GvGP_set(gv,gp) ((gv)->sv_u.svu_gp = (gp))
# define GvFLAGS(gv) (GvXPVGV(gv)->xpv_cur)
# define GvSTASH(gv) (GvXPVGV(gv)->xnv_u.xgv_stash)
# define GvNAME_HEK(gv) (GvXPVGV(gv)->xiv_u.xivu_namehek)
Indeed, the purpose was making GvGP
read-only by making an r-value.
CodePudding user response:
It makes it an rvalue i.e. you cannot do &(0 (gv)->sv_u.svu_gp)
; furthermore, if it were instead an array, i.e. 0 "string"
, it would also decay the array to a char *
from a char [7]
-- so essentially std::decay
.