How to convert GMP C parameter convention into something more natural?

☆樱花仙子☆ 提交于 2019-12-07 21:44:42

问题


For example, I would like to do something like this:

#include <gmp.h>
typedef mpz_t Integer;

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

But, GMP doesn't let me do this, apparently mpz_t is an array, so I get the error:

error: ‘F’ declared as function returning an array

So instead I would have to do something like this:

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); 
}

This is unnatural, and not following the logical way that C (or in general mathematical) expressions can be composed. In fact, you can't compose anything in a math-like way because apparently you can't return GMP numbers! If I wanted to write - for example - a simple yacc/bison style parser that converted a simple syntax using +, -, /, * etc. into C code implementing the given expressions using GMP it seems it would be much more difficult as I would have to keep track of all the intermediate values.

So, how can I force GMP to bend to my will here and accept a more reasonable syntax? Can I safely "cheat" and cast mpz_t to a void * and then reconstitute it at the other end back into mpz_t? I'm assuming from reading the documentation that it is not really passing around an array, but merely a reference, so why can't it return a reference as well? Is there some good sound programming basis for doing it this way that I should consider in writing my own program?


回答1:


From gmp.h:

typedef __mpz_struct mpz_t[1];

This makes a lot of sense, and is pretty natural. Think about it: having an array of size 1 allows you to deal with an obscured pointer (known as opaque reference) and all its advantages:

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

Were it not an array, you'd have to do something like:

mpz_t number;
DoubleIt(&number);

And then it comes all the confusion. The intention behind the opaque type is to hide these, so you don't have to worry about it. And one of the main concerns should be clear: size (which leads to performance). Of course you can't return such struct that holds data limited to the available memory. What about this one (consider mpz_t here as a "first-class" type):

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

You (the program) would have to copy all the data in number and push it as a parameter to your function. Then it needs to leave appropriate space for returning another number even bigger.

Conclusion: as you have to deal with data indirectly (with pointers) it's better to use an opaque type. You'll be passing a reference only to your functions, but you can operate on them as if the whole concept was pass-by-reference (C defaults to pass-by-reference).



来源:https://stackoverflow.com/questions/9916401/how-to-convert-gmp-c-parameter-convention-into-something-more-natural

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!