By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,804 Members | 1,681 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,804 IT Pros & Developers. It's quick & easy.

Cannot 'new' a GMP object

P: n/a
#include <gmp.h>

mpz_t* p_mympz = new mpz_t;

error: cannot convert '__mpz_struct*' to '__mpz_struct (*)[1]' in
initialization

1. What does that mean?

2. Given that mpz_t doesn't have a constant sizeof() I take it that
dynamic creation (new/delete) is the only way I can create an array of
them (that is, keep their pointers in an array and use the -> operator).
Jul 23 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Richard Cavell wrote:
#include <gmp.h>

mpz_t* p_mympz = new mpz_t;

error: cannot convert '__mpz_struct*' to '__mpz_struct (*)[1]' in
initialization

1. What does that mean?
Seems that mpz_t is a typedef for an array. If you allocate an array with
new, you get a pointer to the first element, not a pointer to the array.
Anyway, I wonder why there would be a typedef for an array with exactly one
element.
2. Given that mpz_t doesn't have a constant sizeof()
What do you mean? sizeof() is resolved at compile time. It _always_ returns
a compile-time constant.
I take it that dynamic creation (new/delete) is the only way I can create
an array of them (that is, keep their pointers in an array and use the ->
operator).


Well, if the number of elements is not know until it is created, yes.
However, you can use std::vector instead, which handles the memory
management details for you.

Jul 23 '05 #2

P: n/a
On 18/2/05 8:47 PM, Rolf Magnus wrote:
Seems that mpz_t is a typedef for an array. If you allocate an array with
new, you get a pointer to the first element, not a pointer to the array.
Anyway, I wonder why there would be a typedef for an array with exactly one
element.
typedef __mpz_struct mpz_t[1];

__mpz_struct is typedef'ed to a struct which has 2 ints and one pointer.
The GMP code is too advanced for me but I'm guessing that mpz_t[1] is
intended to point to the end of the structure rather than the start.
What do you mean? sizeof() is resolved at compile time. It _always_ returns
a compile-time constant.


I'm making the point, though, that if I could know that sizeof() were
constant I could create vector<mpz_t> instead of vector<mpz_t*>
Jul 23 '05 #3

P: n/a
On Fri, 18 Feb 2005 21:56:33 +1100, Richard Cavell
<ri***********@mail.com> wrote:
On 18/2/05 8:47 PM, Rolf Magnus wrote:
Seems that mpz_t is a typedef for an array. If you allocate an array with
new, you get a pointer to the first element, not a pointer to the array.
Anyway, I wonder why there would be a typedef for an array with exactly one
element.


typedef __mpz_struct mpz_t[1];

__mpz_struct is typedef'ed to a struct which has 2 ints and one pointer.
The GMP code is too advanced for me but I'm guessing that mpz_t[1] is
intended to point to the end of the structure rather than the start.


It's declared that way so that a C program can pass it as a sort of
reference parameter:

mpz_t a, b, c;
mpz_init2(a, 1);
mpz_init2(b, 2);
mpz_init(c);
mpz_add(c, a, b);

instead of having to put & in front of all of the variables to pass them
as pointers explicitly. Unfortunately this really messes with the types
in C++, and I wouldn't guarantee that vector<> and other containers work
properly (I remember having some problems at one time, but I'm not sure
whether they now work).
What do you mean? sizeof() is resolved at compile time. It _always_ returns
a compile-time constant.


I'm making the point, though, that if I could know that sizeof() were
constant I could create vector<mpz_t> instead of vector<mpz_t*>


Try using the C++ wrapper instead (mpz_class). Its major disadvantage
is that it sets up each variable every time it is created, including
temporaries:

mpz_class a, b, c;
a = 1;
b = "2000";
c = a + (a * b);

will allocate a temporary for (a * b) and initialise it, then throw it
away after use, calling malloc() and free(), which takes a lot of time.
If you stick to simple expressions though this won't happen (it has
optimisations so that (x = a + b; and the like are done as a single
operation). For instance, I've done timings on the following:

r = (a*b + c*d) / (a + b*c + d);

r = a*b;
tmp = c*d;
r += tmp;
tmp = b*c;
tmp += a;
tmp += d;
r /= tmp;

and the differences (on Debian GNU/Linux 'woody', Duron 1200 CPU) are a
factor of 3-4 for mpz_class and a factor of 2 for mpf_class (floating
point, both with default precision 128). The second form is comparable
in speed to using the C GMP functions directly.

Chris C
Jul 23 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.