-3

On migrating a project from vc++ 6.0 to vs 2008, I get the below warnings. Can anyone please explain me why this warning occurs?

inline tstring& tstring::trim()
{
    long lDelFront = 0, lDelBack = 0;

    while (lDelFront < length() && at(lDelFront) == ' ')      //C4018 Warning
        lDelFront++;

    if ( lDelFront > 0 )
    {
        erase(0, lDelFront);
    }

    while (lDelBack < length() &&                       //C4018 Warning
            at(length() - lDelBack - 1) == ' ')
        lDelBack++;

    if ( lDelBack > 0 )
    {
        erase(length() - lDelBack, lDelBack);
    }

    return *this;
}

Thanks! Ankush

Hulk
  • 6,399
  • 1
  • 30
  • 52
user3360310
  • 447
  • 1
  • 6
  • 17
  • 1
    The problem is - "signed/unsigned mismatch" in '<'. What's unclear? You compare signed and unsigned numbers. Most probably, `lDelBack` is signed and `length()` returns unsigned or the other way around. Or you're asking what is the problem with this? – Kiril Kirov Mar 05 '14 at 08:51
  • The warning is because C++ (and C) has idiotic integer promotion rules. `lDelFront` is signed and `length()` is unsigned, which results in `lDelFront` being converted to `unsigned long` and if it has a negative value then it suddenly becomes very large. – Simple Mar 05 '14 at 08:57
  • Please, properly indent your code when posting to SO. Also you should give us types of all variables in a line with warning. – zoska Mar 05 '14 at 09:07

3 Answers3

4

length() probably returns size_t or unsigned long and you are comparing it with signed long. Change

long lDelFront = 0, lDelBack = 0;

to

size_t lDelFront = 0;
size_t lDelBack = 0;

to avoid signed/unsigned comparison

Blaz Bratanic
  • 2,279
  • 12
  • 17
4

The question doesn't provide enough context, in particular the prototype of length() is missing. We do know that long is a signed integer (see here) and from the warning we can guess that length() returns an unsigned integer.

You can't just compare signed and unsigned integers and expect sensible results. That is because the sign bit (the "left-most" bit) is interpreted differently when you compare signed or unsigned numbers. For example:

signed char c1 = 0x80;    // that's a -127 decimal
unsigned char c2 = 0x80;  // that's a 128 decimal

If you perform a greater-than or less-than comparison with these numbers and mix signedness, then it is not clear how to compare these values because the result is different for each of the two. (Note that this wouldn't happen for equal/not-equal comparison.) For example:

bool greater = c1 > 0;    // false, because 0x80 interpreted as signed number is negative
bool greater = c2 > 0;    // true, because 0x80 interpreted as unsigned number is positive

And the compiler tells you about this issue with the warning you've encountered. More details about this warning are here.

The proper solution to fix the warning would be to change the long to an unsigned long, to match the return type of the length() function.

Jens
  • 8,423
  • 9
  • 58
  • 78
0

C++ cannot compare two different types, so it converts them to the same type. Converting signed to unsigned changes the values for negative numbers.

 unsigned u = 10;
 int i = -1;
 if (u > i)
     DoSomething();

to compare these, it might change i to unsigned, which gives us 10 > 4294967295, which might surprise you

Michael J
  • 7,631
  • 2
  • 24
  • 30