Cannot 'new' a GMP object

Discussion in 'C++' started by Richard Cavell, Feb 18, 2005.

  1. #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).
    Richard Cavell, Feb 18, 2005
    #1
    1. Advertising

  2. Richard Cavell

    Rolf Magnus Guest

    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.
    Rolf Magnus, Feb 18, 2005
    #2
    1. Advertising

  3. 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*>
    Richard Cavell, Feb 18, 2005
    #3
  4. On Fri, 18 Feb 2005 21:56:33 +1100, Richard Cavell
    <> 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
    Chris Croughton, Feb 18, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Richard Cavell

    GMP: Cannot operate on vector<mpz_t>

    Richard Cavell, Feb 18, 2005, in forum: C++
    Replies:
    3
    Views:
    1,105
    Richard Cavell
    Feb 18, 2005
  2. Replies:
    4
    Views:
    1,091
  3. Allen Harkleroad
    Replies:
    0
    Views:
    446
    Allen Harkleroad
    Sep 5, 2007
  4. Jasper
    Replies:
    4
    Views:
    268
    Sisyphus
    Jun 29, 2004
  5. Senthilkumar T
    Replies:
    4
    Views:
    355
    Sherm Pendley
    Jul 15, 2004
Loading...

Share This Page