warning C4239: operator overloading

Dear all,

I am writing my own classes for operations with large integers (as an exercise, although I plan on switching to the standard GMP library).

While overloading the operator /, I got
warning C4239:nonstandard extension used : 'argument' : conversion from X to Y A reference that is not to 'const' cannot be bound to a non-lvalue; assigment operator takes a reference to non-const
.

Here is my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class LargeInt:public ListBasicObjects<unsigned int>
{
public:
  void operator= (LargeInt& x); 
  LargeInt operator/(int x);
  LargeInt(LargeInt& x);
  LargeInt(){};
};

/*...later in the code:*/
void foo(LargeInt& BigN)
{ int base=10;
  LargeInt tempInt;
  tempInt=BigN/base; //warning C4239
}

The code does what it is supposed to, the only problem is that annoying warning. What am I doing wrong? Thanks!
Last edited on
Only thing I can think of is that bigN/base will produce a temporary LargeInt type which gets assigned to tempInt via the = operator. Because the = operator is overloaded, this temporary value is actually a seperate variable that is passed to a function. And because it's temporary, it's being treated as a 'const LargeInt' and not a nonconst LargeInt -- but your assignment operator only takes nonconst.

My suggested solution is to declare things as const that you don't need to be nonconst. In this particular case, this means changing the = operator to take a const LargeInt& x instead of just LargeInt& x.

However you might want to make the = operator more intuitive as well (have it return a reference to itself, rather than a void), and const up some other things as well:

1
2
3
4
5
6
7
class LargeInt : public ListBasicObjects<unsigned int>
{
public:
  LargeInt& operator = (const LargeInt& x); // "return *this;" after assignment
  LargeInt operator / (int x) const; // declare this function as const because it doesn't change *this
  //etc
};
Thanks for the good advice! While trying to implement it I ran into error C2664: Converting parameter 1 from 'const LargeInt' into 'LargeInt &' not possible.


class LargeInt:public ListBasicObjects<unsigned int>
{
public:
void operator= (const LargeInt& x);
void Assign(LargeInt& x);
void Assign(const LargeInt& x);
LargeInt operator/(int x)const;
LargeInt(LargeInt& x);
LargeInt(){};
};

void LargeInt::operator =(const LargeInt& x)
{ this->Assign(x);//error C2664 here!
}


Now, I prefer to keep only one assignment function in the whole code to make future optimizations quicker and to avoid repeating errors. What would you suggest me to do?


[Edit] Just figured it out! I only need to change
 
void Assign(const LargeInt& x);


A question related to that. With the above definition, what happens if I call this->Assign(*this);? In other words, what is the purpose of the const above?

Last edited on
Assign also needs to take its parameter by const reference.

Also your "copy constructor".

again this comes back to the const/nonconst issue.

If you're taking references as parameters, make them const unless you will be changing their value. So your Assign() function, as well as the copy ctor should be taking const LargeInt&.

You might also want to make Assign const as well, since that probably isn't changing *this.

This all seems like it's silly, and it might be best to avoid this const stuff altogether.. but doing it right can prevent some funky problems in the future:

1
2
3
4
5
6
7
8
9
10
class //...
{
public:
  LargeInt& operator = (const LargeInt& x);
  void Assign(const LargeInt& x) const;
  LargeInt operator / (int x) const;

  LargeInt();
  LargeInt(const LargeInt& x);
};


EDIT -- glad you got it fixed

A question related to that. With the above definition, what happens if I call this->Assign(*this);? In other words, what is the purpose of the const above?


Taking const references allows you to use constant values instead of nonconst variables. For example:

1
2
LargeInt i;
i = 5;  // might error because 5 is a const literal, not a nonconst variable 


nonconst vars can be be passed as const, but not the other way around. So making references const ensures that both const and nonconst parameters will work. Whereas if you fail to specify const, only nonconst parameters will work.
Last edited on
Thanks both of you! will do it the right way hehe...
Topic archived. No new replies allowed.