Porting from Windows to Linux

P

Prasanna

Hi,

I have been developing some libraries using VC++ 6.0. My work is
complete now and the code works just fine. It has been tested under
many circumstances and i have not encountered any problems. Now, I
would like to port it to gcc. Initially compiling it with gcc produced
a few errors, asking for some 'const' declarations in places where
VC++ would not bother to. But then, i was able to compile it and
create an executable. The problem is the executable crashes when i run
it.

I tried it with cygwin latest version and g++ in suse 8.1. When i
tried to debug it with DDD in suse, the program halts when i am
returning a reference. I checked for possible memory problems, like
returning a reference for a local variable or chaning the address of
an allocated memory. But there are none like that.

For example, the place where my program halts is this:

vector<unsigned>& GF::primitive()
{
return ir;
}

where 'ir' is a protected data member of class GF, as shown.

class GF{
....
protected:
vector<unsigned> ir;
};

If i try to step through return, it goes inside vector class and i get
lost.
I have no idea why this happens. Can someone elighten me on this.

Regards,
Prasanna.
 
R

Rolf Magnus

Prasanna said:
Hi,

I have been developing some libraries using VC++ 6.0. My work is
complete now and the code works just fine. It has been tested under
many circumstances and i have not encountered any problems. Now, I
would like to port it to gcc. Initially compiling it with gcc produced
a few errors, asking for some 'const' declarations in places where
VC++ would not bother to. But then, i was able to compile it and
create an executable. The problem is the executable crashes when i run
it.

I tried it with cygwin latest version and g++ in suse 8.1. When i
tried to debug it with DDD in suse, the program halts when i am
returning a reference. I checked for possible memory problems, like
returning a reference for a local variable or chaning the address of
an allocated memory. But there are none like that.

For example, the place where my program halts is this:

vector<unsigned>& GF::primitive()
{
return ir;
}

where 'ir' is a protected data member of class GF, as shown.

class GF{
...
protected:
vector<unsigned> ir;
};

The debugger should tell you more, like the parameters (including the
'this' pointer). Maybe on the call to primitive, 'this' was a null
pointer.
 
I

Ioannis Vranos

Prasanna said:
Hi,

I have been developing some libraries using VC++ 6.0. My work is
complete now and the code works just fine. It has been tested under
many circumstances and i have not encountered any problems. Now, I
would like to port it to gcc. Initially compiling it with gcc produced
a few errors, asking for some 'const' declarations in places where
VC++ would not bother to. But then, i was able to compile it and
create an executable. The problem is the executable crashes when i run
it.

I tried it with cygwin latest version and g++ in suse 8.1. When i
tried to debug it with DDD in suse, the program halts when i am
returning a reference. I checked for possible memory problems, like
returning a reference for a local variable or chaning the address of
an allocated memory. But there are none like that.

For example, the place where my program halts is this:

vector<unsigned>& GF::primitive()
{
return ir;
}

where 'ir' is a protected data member of class GF, as shown.

class GF{
....
protected:
vector<unsigned> ir;
};

If i try to step through return, it goes inside vector class and i get
lost.
I have no idea why this happens. Can someone elighten me on this.

Regards,
Prasanna.



Does the following code crash to you?


#include <vector>


int main()
{
using std::vector;

class test
{
protected:
vector<unsigned>ir;

public:
vector<unsigned>& primitive() { return ir; }
};


test a;

vector<unsigned> &rir=a.primitive();
}






Regards,

Ioannis Vranos
 
P

Prasanna

I was able to locate the problem. The problem is:

class GF{

public:
GF(){};
GF(vector<unsigned>);
GF(vector<unsigned>, unsigned);
GF(GF&);

GF& operator=(vector<unsigned>&);
GF& operator=(GF&);

vector<unsigned> primitive();
vector<unsigned> element();

protected:

vector<unsigned> ir;
vector<unsigned> el;
};

I am using the above class in a code segment like this:

//////////////
.....
vector<GF> f;
GF local;
f.push_back(local); // just to demonstrate the problem

unsigned m = f.size();

for(int i=0;i<m;i++)
f = GF(local.primitive(),i).element(); //<-- this is where it
crashes
......
//////////////

What i want the above line to do is create a GF object and assign its
element to f using operator =. VC++ is doing only that. But gcc
does the following. It creates a GF object and uses its element
returned by GF::element() to create another GF object using the
GF::GF(vector<unsigned>) constructor and then uses GF::eek:perator=(GF&)
to assign it to f.

May be this is a ill formed situation. But neither gcc nor vc++ issues
any warnings about it. Can u suggest me some good solution, coz i also
want this GF::GF(vector<unsigned>). That makes usage of the class
quite easier.

Regards,
Prasanna.
 
I

Ioannis Vranos

Prasanna said:
I was able to locate the problem. The problem is:


Ok let's give it a try.


class GF{

public:
GF(){};
GF(vector<unsigned>);
GF(vector<unsigned>, unsigned);


The above two have as a result vectors with all their contents to be
copied with the space and time cost this implies. I do not know which
vector (ir or el) you initialize with the vector<unsigned> above but
here is an example:


GF(const vector<unsigned> &v):ir(v) { // or ir=v; }
GF(const vector<unsigned> &v, unsigned x): ir(v) { // whatever else }




// Type safety
GF(const GF &);





GF& operator=(vector<unsigned>&);



Better defined outside of the class as

// const again too
GF& operator=(GF&);

GF& operator=(const GF&);


vector<unsigned> primitive();
vector<unsigned> element();


These two return these or references? If you need only the values and
not direct access to ir, el you had better make the above


// References returned, run-time efficiency
const vector<unsigned> &primitive() const;
const vector<unsigned> &element() const;


protected:

vector<unsigned> ir;
vector<unsigned> el;
};

I am using the above class in a code segment like this:

//////////////
.....
vector<GF> f;
GF local;
f.push_back(local); // just to demonstrate the problem

unsigned m = f.size();


vector<GF>::size_type m=f.size();

but is not needed anyway, see below.


for(int i=0;i<m;i++)


for(vector<GF>::size_type i=0; i<f.size(); ++i)


f = GF(local.primitive(),i).element(); //<-- this is where it
crashes



Many conversions take place here. However you are passing i which has
the value 0 and i do not know how you use the unsigned inside the
implementation of GF constructor. Perhaps the problem lies there.

However i have not understood what you want to do with the above. Why
create a temporary GF in the first place?



......
//////////////

What i want the above line to do is create a GF object and assign its
element to f using operator =. VC++ is doing only that. But gcc
does the following. It creates a GF object and uses its element
returned by GF::element() to create another GF object using the
GF::GF(vector<unsigned>) constructor and then uses GF::eek:perator=(GF&)
to assign it to f.



Yes, because f is a GF object, while GF::element() returns a
vector<unsigned> object, so implicit type conversion is taking place in
both compilers. Of course a compiler can optimise some of these
conversions out, if possible. However we must think without any such
compiler optimisations in mind.


If possible, provide the implementations of all the constructors.






Regards,

Ioannis Vranos
 
R

Rolf Magnus

Ioannis said:
Better defined outside of the class as
Why?


// const again too
GF& operator=(GF &, const vector<unsigned>&);

That won't compile. operator= cannot be defined as non-member.
 
I

Ioannis Vranos

Rolf said:
That won't compile. operator= cannot be defined as non-member.



Oops you are right. I had to define an operator for some time and I have
become rusty.






Regards,

Ioannis Vranos
 
P

Prasanna

The above two have as a result vectors with all their contents to be
copied with the space and time cost this implies. I do not know which
vector (ir or el) you initialize with the vector<unsigned> above but
here is an example:


GF(const vector<unsigned> &v):ir(v) { // or ir=v; }
GF(const vector<unsigned> &v, unsigned x): ir(v) { // whatever else }

I intialize ir. And i have changed it to the references.
These two return these or references? If you need only the values and
not direct access to ir, el you had better make the above


// References returned, run-time efficiency
const vector<unsigned> &primitive() const;
const vector<unsigned> &element() const;

I will change these too. The thing is STL gave me a lot of problems
with using references and consts', expecially with this operator ==.
So i messed up my code a bit.
vector<GF>::size_type m=f.size();

but is not needed anyway, see below.

But why? That makes the code harder to read is not it? I have no idea
to what type is vector said:
for(int i=0;i<m;i++)


for(vector<GF>::size_type i=0; i<f.size(); ++i)


f = GF(local.primitive(),i).element(); //<-- this is where it
crashes



Many conversions take place here. However you are passing i which has
the value 0 and i do not know how you use the unsigned inside the
implementation of GF constructor. Perhaps the problem lies there.
However i have not understood what you want to do with the above. Why
create a temporary GF in the first place?



It is not absolutely required (creating a local variable). To explain
it, the objects are some kind of polynomials. What i do in the
constructor is to create one such polynomial of degree i. I can
ofcourse change it by creating a initial constant and then shifting it
(which is multiplying it by x). But that is not the exact problem
because the code also crashes in the following place.

for(i=0;i<=fx.degree();i++){
irp.push_back(baserep);
irp = fx.element();
}

And the problem is the same. gcc uses the constructor than using the
operator =.
Yes, because f is a GF object, while GF::element() returns a
vector<unsigned> object, so implicit type conversion is taking place in
both compilers. Of course a compiler can optimise some of these
conversions out, if possible. However we must think without any such
compiler optimisations in mind.


I did not have any compiler optimizations in mind. What vc++ does is
what i had in mind and it seemed obvious to me that the expression
should be handled that way. Well.. i am learning.
If possible, provide the implementations of all the constructors.

I have pasted below the implementations of some of the overloaded
constructors. It is lot of code reuse, but i dont see any other ways.
:(

GF2m::GF2m() {
irp.push_back(0); elm.push_back(0);
}

GF2m::GF2m(const vector<unsigned>& irr)
{
int i,m,s;
m = irr.size();
if(m!=0){
//! first copy the irreducible polynomial
irp = irr;
//! then, for modular reduction, precompure x^m term
for(i=m-2;i>=0;i--)
if(irp!=0)
break;
s=i;
for(i=0;i<=s;i++)
xm.push_back(irp);
}
else
irp.push_back(0);

elm.push_back(0);
}

GF2m::GF2m(const vector<unsigned>& irr, unsigned exp)
{
int i,m,s;
m = irr.size();
if(m!=0){
irp = irr;
for(i=m-2;i>=0;i--)
if(irp!=0)
break;
s=i;
for(i=0;i<=s;i++)
xm.push_back(irp);
}
else
irp.push_back(0);

elm.resize(exp+1);
//! form, x^k, k = exp;
for(i=0;i<exp;i++)
elm=0;
elm[exp] = 1;

if(exp>=m-1)
reduce(); //! reduce modulo irreducible
}

GF2m::GF2m(const vector<unsigned>& irr, vector<unsigned> e)
{
int i,m;
m = irr.size();
if(m!=0){
irp = irr;
for(i=m-2;i>=0;i--)
if(irp!=0)
break;
unsigned s=i;
for(i=0;i<=s;i++)
xm.push_back(irp);
}
else
irp.push_back(0);

if(!e.empty())
elm = e;
else
elm.push_back(0);

}

Best regards,
Prasanna.
 
I

Ioannis Vranos

Prasanna said:
I will change these too. The thing is STL gave me a lot of problems
with using references and consts', expecially with this operator ==.
So i messed up my code a bit.


The safety of the type system is there to help and protect you, provided
that you use it correctly (e.g. declare as constant only things not
intended to be modified).

But why? That makes the code harder to read is not it? I have no idea
to what type is vector<T>::size_type defined to.



vector<T>::size_type is the type returned from vector<T>::size() member
function. In most cases it is a typedef of an unsigned integral type.

However there may be a specialisation for a particular T type, even from
you for a type of yours. As you can understand, you can go really
abstract and you are limited only by your imagination to create
"things". :)

To be portable it is better to use size_type instead of size_t since it
is the type returned by size(). If you are tired to write
vector<GF>::size_type all the time you can do a typedef:


typedef vector<GF>::size_type size;

// ...

for(size i=0; i<f.size() ++i)
// ...


// ...

for(size i=0; i<f.size() ++i)
// ...

It is not absolutely required (creating a local variable). To explain
it, the objects are some kind of polynomials. What i do in the
constructor is to create one such polynomial of degree i.



Ok you had written:


"class GF{

public:
GF(){};
GF(vector<unsigned>);
GF(vector<unsigned>, unsigned);
GF(GF&);

GF& operator=(vector<unsigned>&);
GF& operator=(GF&);

vector<unsigned> primitive();
vector<unsigned> element();

protected:

vector<unsigned> ir;
vector<unsigned> el;
};



//////////////
......
vector<GF> f;
GF local;
f.push_back(local); // just to demonstrate the problem

unsigned m = f.size();

for(int i=0;i<m;i++)
f = GF(local.primitive(),i).element(); //<-- this is where it
crashes
.......
//////////////"



The local.primitive() in the constructor call returns an *empty*
vector<unsigned>, and i used is 0. I think the first or the second or
both is the reason of the crash.










I can
ofcourse change it by creating a initial constant and then shifting it
(which is multiplying it by x). But that is not the exact problem
because the code also crashes in the following place.

for(i=0;i<=fx.degree();i++){
irp.push_back(baserep);
irp = fx.element();
}

And the problem is the same. gcc uses the constructor than using the
operator =.

Yes, because f is a GF object, while GF::element() returns a
vector<unsigned> object, so implicit type conversion is taking place in
both compilers. Of course a compiler can optimise some of these
conversions out, if possible. However we must think without any such
compiler optimisations in mind.



I did not have any compiler optimizations in mind. What vc++ does is
what i had in mind and it seemed obvious to me that the expression
should be handled that way. Well.. i am learning.



Whatever the optimisations the result should be the same, otherwise that
would mean that it can't be optimised.


I have pasted below the implementations of some of the overloaded
constructors. It is lot of code reuse, but i dont see any other ways.
:(

GF2m::GF2m() {
irp.push_back(0); elm.push_back(0);
}

GF2m::GF2m(const vector<unsigned>& irr)
{
int i,m,s;
m = irr.size();



vector<unsigned>::size_type i, m, s;

etc.. Or at least an unsigned built in integral type, like unsigned.


if(m!=0){
//! first copy the irreducible polynomial
irp = irr;
//! then, for modular reduction, precompure x^m term
for(i=m-2;i>=0;i--)
if(irp!=0)
break;
s=i;
for(i=0;i<=s;i++)
xm.push_back(irp);
}
else
irp.push_back(0);

elm.push_back(0);
}

GF2m::GF2m(const vector<unsigned>& irr, unsigned exp)
{
int i,m,s;
m = irr.size();
if(m!=0){
irp = irr;
for(i=m-2;i>=0;i--)
if(irp!=0)
break;
s=i;
for(i=0;i<=s;i++)
xm.push_back(irp);
}
else
irp.push_back(0);

elm.resize(exp+1);
//! form, x^k, k = exp;
for(i=0;i<exp;i++)
elm=0;
elm[exp] = 1;

if(exp>=m-1)
reduce(); //! reduce modulo irreducible
}

GF2m::GF2m(const vector<unsigned>& irr, vector<unsigned> e)
{
int i,m;
m = irr.size();
if(m!=0){
irp = irr;
for(i=m-2;i>=0;i--)
if(irp!=0)
break;
unsigned s=i;
for(i=0;i<=s;i++)
xm.push_back(irp);
}
else
irp.push_back(0);

if(!e.empty())
elm = e;
else
elm.push_back(0);

}



Ok i 'll try to check the above tomorrow, however in the mean time try
to use vector::at() in the place of [], which is range checked, for example:

for(i=m-2;i>=0;--i)
if(irp.at(i)!=0)
break;


vector<>::at() throws an exception if its index is out of range.






Regards,

Ioannis Vranos
 
I

Ioannis Vranos

Ioannis Vranos wrote:

Typos fixed:

To be portable it is better to use size_type instead of size_t since it
is the type returned by size(). If you are tired to write
vector<GF>::size_type all the time you can do a typedef:

typedef vector said:

for(Size i=0; i<f.size() ++i)
// ...


// ...

for(Size i=0; i<f.size() ++i)
// ...






Regards,

Ioannis Vranos
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top