Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does `0+ptr` (0 plus a pointer) mean?

Tags:

c

pointers

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?

like image 476
skankhunt76 Avatar asked Sep 03 '21 07:09

skankhunt76


People also ask

What does pointer == 0 mean in C?

if (pointer == 0) 0 is another representation of the null pointer constant. if (!pointer) This if statement implicitly checks "is not 0", so we reverse that to mean "is 0".

What happens when you add 1 pointer?

Pointer Arithmetic Unlike regular numbers, adding 1 to a pointer will increment its value (a memory address) by the size of its underlying data type. To simplify the logic behind this, think of pointer arithmetic the same way you think about array indexing.

What is the difference between ptr and * ptr?

When you do: int* ptr; You are declaring a pointer of type integer named ptr. When you do: *ptr; You tell the program to point to the address stored in ptr.

Can you set a pointer to 0?

You can assign 0 into a pointer: ptr = 0; The null pointer is the only integer literal that may be assigned to a pointer.


2 Answers

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.

like image 74
tstanisl Avatar answered Sep 23 '22 03:09

tstanisl


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.

like image 43
Lewis Kelsey Avatar answered Sep 26 '22 03:09

Lewis Kelsey