如何将GMP C参数约定转换为更自然的东西?

例如,我想做这样的事情:

#include  typedef mpz_t Integer; // Integer F(Integer a,Integer b,Integer c,Integer d) { Integer ret = times(plus(a,b),plus(c,d)); } 

但是,GMP不允许我这样做,显然mpz_t是一个数组,所以我得到错误:

 error: 'F' declared as function returning an array 

所以相反,我必须做这样的事情:

 void F(Integer ret,Integer a,Integer b,Integer c,Integer d) { Integer tmp1,tmp2; plus(tmp1,a,b); plus(tmp2,c,d); times(ret,tmp1,tmp2); } 

这是不自然的,并不遵循可以组成C(或一般数学)表达式的逻辑方式。 事实上,你不能用数学方式编写任何东西,因为显然你不能返回GMP数字! 如果我想编写 – 例如 – 一个简单的yacc / bison样式解析器,使用+, – ,/,*等将简单语法转换为使用GMP实现给定表达式的C代码,它似乎会变得更加困难,因为我必须跟踪所有中间值。

那么,我怎样才能强迫GMP屈服于我的意愿并接受更合理的语法? 我可以安全地“欺骗”并将mpz_t转换为void *然后在另一端将其重新组合成mpz_t吗? 我假设从阅读文档中它并没有真正传递数组,而只是一个引用,那么为什么它也不能返回引用呢? 这样做是否有一些良好的声音编程基础我应该考虑编写自己的程序?

gmp.h

 typedef __mpz_struct mpz_t[1]; 

这很有意义,而且非常自然 。 想一想:拥有一个大小为1的数组可以让你处理一个模糊的指针(称为不透明引用)及其所有优点:

 mpz_t number; DoubleIt(number); /* DoubleIt() operates on `number' (modifies it) as it will be passed as a pointer to the real data */ 

如果它不是数组,你必须做类似的事情:

 mpz_t number; DoubleIt(&number); 

然后它出现了所有混乱。 opaque类型背后的意图是隐藏它们,因此您不必担心它。 其中一个主要问题应该是明确的:规模(导致绩效)。 当然,您无法返回将数据限制在可用内存中的结构。 这个怎么样(将mpz_t视为“一流”类型):

 mpz_t number = ...; number = DoubleIt(number); 

您(程序)必须复制所有数据并将其作为参数推送到您的函数中。 然后它需要留下适当的空间来返回更大的另一个数字。

结论:由于您必须间接处理数据(使用指针),因此最好使用opaque类型。 您将仅将参考传递给您的函数,但您可以对它们进行操作,就好像整个概念都是通过引用 传递一样 (C默认为传递引用 )。