zlenyk
zlenyk

Reputation: 1010

Static initialization C++, value not set

I'am writing a program with a few files, let's assume that all includes are ok. Here is shortened code. ZZ.hpp:

class ZZ
{
    public:
        ZZ(ZZ const & a) { mpz_init_set(data, a.data); }
        ZZ(int a = 0) { mpz_init_set_si(data, a); }
.
.
.

ZZmodN.hpp:

template <unsigned ID>
class ZZmodN
{
    public:
    ZZmodN() = default;
    ZZmodN(ZZmodN const &) = default;
    template <typename T>
    ZZmodN(T const & a) : value(a) { value %= modulus; }
.
.
.    
    private:
    ZZ value;
    static ZZ modulus;
};
template <unsigned ID>
ZZ ZZmodN<ID>::modulus(19);
.
.
.

Polynomial.h:

class Polynomial{
    public:
    std::vector<ZZmodN<0> > co;
    Polynomial(){};
    Polynomial(ZZmodN<0> a){
        co.push_back(a);
    }
.
.

and finally Field.h:

#include "Polynomial.h"
class Field{
    public:
    static Polynomial f;
    Polynomial poly;
    Field(){}
.
.
};
Polynomial Field::f = Polynomial(1);  

the problem is: I'm receiving Floating point exception when I call last (*) line, because 'modulus' = 0 when value %= modulus; is called. Why is it 0 and not 19? I checked, and ZZ constructor with 19 is called. Please help.

Upvotes: 0

Views: 130

Answers (2)

CuriousGeorge
CuriousGeorge

Reputation: 7400

If you make modulus a function, like in the code below, your problem should go away. _m must be initialized before modulus() can return.

template <unsigned ID>
class ZZmodN
{
public:
    ZZmodN() = default;
    ZZmodN(ZZmodN const &) = default;
    template <typename T>
    ZZmodN(T const & a) : value(a) { value %= modulus(); } // changed

// ...

private:
    ZZ value;

    // static ZZ modulus;

    static ZZ modulus()
    {
        static ZZ _m(19);
        return _m;
    }
};

//template <unsigned ID>
//ZZ ZZmodN<ID>::modulus(19);

Upvotes: 1

Adam Rosenfield
Adam Rosenfield

Reputation: 400304

The problem you're running into is the static initialization order fiasco. In your case, the linker is deciding to initialize Field::f before it initializes ZZmodN<0>::modulus.

Upvotes: 6

Related Questions