大小为 1 的 Typedef(匿名)结构数组

Typedef (anonymous) struct array of size 1

所以最近我一直在为我正在进行的项目研究 GMP 的内部结构,我遇到了一个对我来说意义不大的结构:(取自 header 版本 6.2.1)

/* For reference, note that the name __mpz_struct gets into C++ mangled
   function names, which means although the "__" suggests an internal, we
   must leave this name for binary compatibility.  */
typedef struct
{
  int _mp_alloc;        /* Number of *limbs* allocated and pointed
                   to by the _mp_d field.  */
  int _mp_size;         /* abs(_mp_size) is the number of limbs the
                   last field points to.  If _mp_size is
                   negative this is a negative number.  */
  mp_limb_t *_mp_d;     /* Pointer to the limbs.  */
} __mpz_struct;

#endif /* __GNU_MP__ */


typedef __mpz_struct MP_INT;    /* gmp 1 source compatibility */
typedef __mpz_struct mpz_t[1];

在此处的最后一行,我们将 def mpz_t 键入为包含 __mpz_struct 的大小为 1 的数组。这对我来说很奇怪,我以前从未见过这样的建筑。我知道这导致 mpz_t 实际上是指向 __mpz_struct 的指针,但这是否等同于

typedef __mpz_struct* mpz_t;

有人能解释一下这背后的逻辑吗?

有了那个typedef,像

这样的变量声明
mpz_t foo;

等同于

__mpz_struct foo[1];

这只会转换为

__mpz_struct *foo;

如果声明在函数参数列表中。否则就是一个普通的数组声明。

给定 typedef __mpz_struct mpz_t[1];,您可以使用 mpz_t foo; 声明一个实际的 mpz_t 对象。这将为 mpz_t.

保留内存

相反,如果类型是typedef __mpz_struct *mpz_t;,那么mpz_t foo;只会给你一个指针。 mpz_t 不会有 space。您将不得不分配它,并且您必须稍后释放它。所以需要更多的代码,这会很麻烦。

同时,当一个mpz_t被传递给一个函数时,由于数组自动转换为指针,所以只传递它的地址。这允许写 mpz_add(z, x, y);,比 mpz_add(&z, &x, &y); 更简洁。程序员之间可能会争论使用类型定义是否容易出错,当代码名义上看起来只是传递一个值时,有效地导致对对象的引用被传递给函数,但这种风格可能更适用于使用 GMP 完成的编程类型。