Is this warning important ?

Pages: 12
Is "Comparison between signed and unsigned" warning important ?

Well most of the time I've found this warning on comparison between index and size something like

1
2
vector<int> p = { 90, 30, 50 , 10 };
for( int i = 0; i < p.size(); ++i ) cout << i << ' ';


I simply think that this is somehow irrelevant.
Well I never found a linear array bigger than 2 Billion members
For example :
 
vector<int> p( 1 << 31 ); // 2 GB 

This has never worked in any of my computer. it always cause run time error.

I really think that in the next few years I won't be making 2GB of linear array anyway. I mean for what perpose did I do that.

So I never really care about this but everyone said to remove all the warnings
and now I am thinking to follow everyone...

Tell me your opinion about whether this warning should be fixed or not
Last edited on
Use size_t instead of int in the for loop to get rid of the warning.
for( size_t i = 0; i < p.size(); ++i ) cout << i << ' ';
ooh the size_t

I found them hard to understad...

Are they signed or unsigend ?
They are both I am assuming
size_t pos = -1;

I also have dilemma on using feature I don't understand.
I simply didn't want to make mistake all over the place
size_t is the type returned by std::vector.size(), it is an unsigned type. In your code you try to compare int (a signed type) with size_t (unsigned type), that's why you get that compiler warning.
oow,

why not use "unsigned" keyword instead of size_t ??
Both are fine to me but I like the unsigned more....

This looping problem could be ignored but sometimes I hate it when it causes hard to be noteciable error

The cases when :

1
2
3
4
5
6
7
8
    size_t x1,x2,y1,y2;
    x1 = 50; y1 = 20;
    x2 = 30; y2 = 100;

    // Think that they are 2D Array Indexes
    // And I need to find a range between the two

    float range = sqrt( pow( x2 - x1, 2 ) + pow( y2-y1, 2 ) );


Casting everytime seems unberable

But remmber when I mention about they being 2D Array indexes
Indexes should always be unsigned ( size_t ) because they are compared with vector.size() which returns unsigned ( size_t )

so tell me about the solution to this problem
Last edited on
why not use "unsigned" keyword instead of size_t ??

Because it could be any unsigned type, for example an unsigned int, unsigned long, or even unsigned char. The standard used size_t so the implementation could determine the correct type for their particular operating system, processor.

so tell me about the solution to this problem

Use size_t when comparing to the size of one of the standard containers. By the way this includes the std::string class. This class also returns a size_t when you use the size() function.
Last edited on
well
unsigned x;
always works as a short version of unsigned int in my compiler

pretty cool huh ?
unsigned is always unsigned int, but size_t can be any unsigned type.

For example, on a typical today's 64-bit system, unsigned int is 32 bit and size_t is 64 bit. You may not be dealing with >4Gb vectors routinely, but others do, and using an unsigned int to iterate such vector would fail on those systems.

PS: to be pedantic, the return type of std::vector<int>::size() is std::vector<int>::size_type, it just happens to be aliased to std::size_t in all sensible implementations.
Last edited on
ok
I will change all to size_t for looping but how about the other problem

The minus operation between 2 unsigned type ?

1
2
3
4
5
6
unsigned a = 1000;
unsigned b = 2000;

cout < a - b << endl; // problem !
cout < b - a << endl; // no problem !


Well if castng is inevitable then I just have to do it

so is there other solution ???
I think that your problem is coming from using the variables that you need for your calculations (which should be signed for subtraction operations) also as index values in your for loops. This causes the "coupling" of type requirements you are experiencing.
Use the different types where they are needed.

The only code I see from your posts where a conflict occurs is here:
1
2
vector<int> p = { 90, 30, 50 , 10 };
for( int i = 0; i < p.size(); ++i ) cout << i << ' ';

But I'm guessing your intent here was to display the values of the int types stored in the vector p, so:
1
2
vector<int> p = { 90, 30, 50 , 10 };
for( unsigned i = 0; i < p.size(); ++i ) cout << p[i] << ' ';

should work fine and produce no warnings. In fact, unsigned is more appropriate for the array index in p[i] also.

Please post a fuller of example of where this "type" conflict occurs in your code, and we can take a closer look.
Well, what I do really doesn't really matter

The problem is warnings I want to remove them or at least make them invisible in the log.

This is similiar case where I have the problem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <vector>
#include <iostream>
#include <cmath>

using namespace std;

int main(){
    vector< vector<unsigned> > array( 20, vector<unsigned>( 20, 0 ) );

    int hx = 9;
    int hy = 9;
    unsigned maxrg = 5;

    // whether it is size_t, unsigned, unsigned long it is it must be unsigned
    // to prevent the warning
    for( size_t x = 0; x < array.size(); ++x ){
        for( size_t y = 0; y < array[x].size(); ++ y ){
            unsigned range = ( unsigned ) sqrt( pow( hx - x, 2 ) + pow( hy - y, 2 ) );

            if( range <= maxrg ) {
                array[x][y] = range;
            }

            cout << array[x][y] << ' ';
        }
        cout << endl;
    }
}


Well this causes unexpected result

This part should have casting
 
unsigned range = ( unsigned ) sqrt( pow( hx - x, 2 ) + pow( hy - y, 2 ) );


like this one
 
unsigned range = ( unsigned ) sqrt( pow( hx - int(x), 2 ) + pow( hy - int(y), 2 ) );


And this is simple case where it happened

But sometimes your equation is just that long and you make it so much longer with casting

Don't really want to do if I don't have to
Last edited on
Apart from making equation so much longer

Well, sometimes I am just to lazy to scroll from line 1000 to line 100 to find the decleration whether it is signed or unsigned

Does it need to be casted to work or not ?
Should I cast the index or the size ??

 
if( i < int( array.size() ) ){}

or
 
if( ( unsigned ) i < array.size() ){}


That's what bothers me the most about this warning

to play safe I might just use int for everything but
they are a hell of a warning if I replace all unsigned to int
Last edited on
sometimes I am just to lazy to scroll from line 1000 to line 100 to find the decleration whether it is signed or unsigned
Use a non-stupid editor that doesn't force you to navigate to a declaration to see it (e.g. that lets see it through tooltips).

It doesn't look like anyone has mentioned this already, so I will. You should ignore this warning and make the cast explicit only if the signed value is guaranteed to be positive. If it's not, insert a check before the comparison to ensure that it is.

Always cast the signed value to unsigned, not the unsigned to signed. For positive values, the former doesn't lose information, while the latter does. Often,
1 < (signed int) 2147483648u
is false, but
(unsigned int) 1 < 2147483648u
is true. One would normally expect that 1 < 2147483648 regardless of hardware details.
> Often 1 < (signed int) 2147483648u is false, but
> (unsigned int) 1 < 2147483648u is true.

They would give identical results.

Before comparing a signed int with an unsigned int, the compiler converts the signed int to an unsigned int.
Huh? Are you sure you read that right? I just tested it and it gave exactly the results I expected.

EDIT: In case it's not very visible, there's a lower case 'u' at the end of 2^31.
Last edited on
> I just tested it

No. My mistake, 1 < (signed int) 2147483648u is not comparing a a signed int with an unsigned int - it is comparing two signed int values.

Thanks for pointing it out.

(With 32-bit integers, (signed int) 2147483648u is std::numeric_limits<int>::min())
Last edited on
If this is windows does not matter if is 32 or 64 bit application, sizeof is always 4.
Why 64 bit will be different and in 32 bit is undefined behaviour ?
> Why 64 bit will be different and in 32 bit is undefined behaviour ?

I made a mistake in counting the bits. My earlier post has been edited.
My apologies for the confusion that has been caused.
Last edited on
ok I will go with the suggestion of using "unsigned" casting
Ehmm, both ways are really is ok
cause I've calculated that my 2D Array won't be anywhere near 2 Billion members

They might be as little as 1024 x 1024
short will do but I don't think short is a good idea

The non-stupid IDE Ehmm I am using Notepad++ and Code::blocks and I am not thinking on moving to anything. My computer is not really that great. Sometimes opening large files such as sqlite causes lag.

Any suggestion for notepad++ plugin or a another non-stupid lightweight IDE ?
the most correct way is to write

for ( std::vector<int>::size_type i = 0; i < v.size(); i++ ) std::cout << v[i] << ' ';

It is not necessary that size_t is equivalent to std::vector<int>::size_type. In fact according to the C++ standard the type that can be used to traverse a vector can be made as

std::make_unsigned<std::iterator_traits<std::vector<int>::iterator>::difference_type>::type i;

Pages: 12