【问题标题】:What does `0+ptr` (0 plus a pointer) mean?`0+ptr`(0 加上一个指针)是什么意思?
【发布时间】:2021-09-03 07:24:45
【问题描述】:

我在Perl的源代码中找到了如下宏:

#define GvGP(gv) (0+(gv)->sv_u.svu_gp)

其中sv_u.svu_gp 在联合sv_u 中声明为GP* svu_gp

我找不到GP 的任何定义。但是,我对 0 加上指针的含义更加困惑。谁能给我指点一下?

【问题讨论】:

  • arco in the source code of Perl 具体在哪里?请张贴链接。
  • 也许可以检查svn_gp 是否不是void*。或者检查它是否是一种算术类型,最终使其成为一个左值,因此不可赋值
  • 仅供参考,GPperl.h 中定义为typedef struct gp GPstruct gpgv.h 中定义。
  • 添加了 perl 标签,以防对 perl 内部非常熟悉的人看到它并解释其中的原理。
  • @TedLyngmo,一元 + 不适用于指针

标签: c pointers


【解决方案1】:

我猜它是用来使其成为 R 值的,什么 在实践中将其设为只读。

示例: 可以写

x = 1;

但这不起作用:

0+x = 1;

编辑

感谢 Dave Mitchell 在 PERL 存储库中指出相关的 commit

添加 GvCV_set() 和 GvGP_set() 宏。

并使 GvCV() 和 GvGP() 仅是右值。 ...

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

确实,目的是通过设置 r 值将 GvGP 设置为只读。

【讨论】:

  • 这很有道理。但是,如果您喜欢 *(0+x) = 1,它仍然是可分配的
  • @skankhunt76,是的,但是这会将0+x 指向的数据分配给0+x,而0+x 本身是不可分配的。
  • 向宏添加 '0+' 的提交明确声明它是强制宏仅是右值(同时添加 GvGP+set() 宏)。
  • link。原来这是我的承诺之一!
  • 这可能被视为不公平的优势 ;-)
【解决方案2】:

它使它成为一个右值,即你不能做&(0+(gv)->sv_u.svu_gp);此外,如果它是一个数组,即0+"string",它也会将数组从char [7] 衰减为char *——所以本质上是std::decay

【讨论】:

  • 太棒了,非常感谢。
猜你喜欢
  • 2022-01-08
  • 2015-03-20
  • 2018-04-09
  • 2018-09-10
  • 2020-01-07
  • 2016-06-03
  • 2014-11-06
  • 2018-09-25
  • 2017-10-29
相关资源
最近更新 更多