size_t and int comparison

T

tings

for (int i=0;i < strlen(pathcmd);i++){//this line cause a warning

warning C4018: '<' : signed/unsigned mismatch

strlen returns a number of type 'size_t'. size_t is an unsigned type and
you are comparing it to an int, a signed type.

Two solutions to remove the warning:

1. Change the type of the variable 'i' to 'size_t'.
2. staic_cast i to "unsigned" type.

Which way is better in C++?
 
M

Mike Wahler

tings said:
for (int i=0;i < strlen(pathcmd);i++){//this line cause a warning

warning C4018: '<' : signed/unsigned mismatch

strlen returns a number of type 'size_t'. size_t is an unsigned type and
you are comparing it to an int, a signed type.

Two solutions to remove the warning:

1. Change the type of the variable 'i' to 'size_t'.
2. staic_cast i to "unsigned" type.

Which way is better in C++?

Change 'i' to type 'size_t'.

Or better yet, replace your char array 'pathcmd'
with a 'std::string' object, and write:

std::string pathcmd("whatever");
for(std::string::size_type i = 0; i < pathcmd.size(); ++i)
/* etc */

(if the code in your loop does not modify the string, you
might get a slight performance improvement by storing the
size before the loop and using that:

std::vector::size_type sz(pathcmd.size());
for(std::vector::size_type i = 0; i < sz; ++i)
/* etc */

-Mike
 
V

Victor Bazarov

tings said:
for (int i=0;i < strlen(pathcmd);i++){//this line cause a warning

warning C4018: '<' : signed/unsigned mismatch

strlen returns a number of type 'size_t'. size_t is an unsigned type and
you are comparing it to an int, a signed type.

Two solutions to remove the warning:

1. Change the type of the variable 'i' to 'size_t'.
2. staic_cast i to "unsigned" type.

3. Ignore the warning.
Which way is better in C++?

It depends on how 'i' is used later. I prefer #3 myself.

Victor
 
V

Victor Bazarov

Mike Wahler said:
[..]
(if the code in your loop does not modify the string, you
might get a slight performance improvement by storing the
size before the loop and using that:

std::vector::size_type sz(pathcmd.size());
for(std::vector::size_type i = 0; i < sz; ++i)
/* etc */

I personally prefer not to pollute scopes with unnecessary names,
so I'd write

for (std::string::size_type sz = pathcmd.size(), i = 0; i < sz; i++) {
...

But it often doesn't matter, probably.

V
 
M

Mike Wahler

Victor Bazarov said:
Mike Wahler said:
[..]
(if the code in your loop does not modify the string, you
might get a slight performance improvement by storing the
size before the loop and using that:

std::vector::size_type sz(pathcmd.size());
for(std::vector::size_type i = 0; i < sz; ++i)
/* etc */

I personally prefer not to pollute scopes with unnecessary names,

So I'm a litterbug. :)
so I'd write

for (std::string::size_type sz = pathcmd.size(), i = 0; i < sz; i++) {

Yes, that's probably better.
...

But it often doesn't matter, probably.

Agreed.

-Mike
 
J

Jerry Coffin

Two solutions to remove the warning:
1. Change the type of the variable 'i' to 'size_t'.
2. staic_cast i to "unsigned" type.

It's giving you a warning because strlen returns a size_t, which is
some unsigned type. You're comparing it to 'i', which is a (signed)
int, and comparing a signed to an unsigned can cause rather strange
results (since each type can normally represent some values the other
can't).

It won't warn you, but you're re-computing the length of the string
every time through the loop. This makes your loop O(N * N) instead of
O(N) -- ugly unless your string is _really_ short. I'd use something
like:

for (int i=0; pathcmd != '\0'; i++) {

Or, perhaps just switch to using an std::string, and while you're at
it, you might want to quit using an explicit loop and replace it with
an algorithm instead:

std::for_each(pathcmd.begin(), pathcmd.end(), do_whatever);

and possibly use boost::lambda to create do_whatever on the fly as
well...
 
D

David Crocker

tings said:
for (int i=0;i < strlen(pathcmd);i++){//this line cause a warning

warning C4018: '<' : signed/unsigned mismatch

strlen returns a number of type 'size_t'. size_t is an unsigned type and
you are comparing it to an int, a signed type.

Two solutions to remove the warning:

1. Change the type of the variable 'i' to 'size_t'.
2. staic_cast i to "unsigned" type.

Which way is better in C++?
(2) is much better. Mixing up 'int' and 'size_t' is a sure way to write
non-portable code. For example, for most 64-bit C++ compilers, size_t is 64
bits whereas int is 32 bits. It's unlikely you would have a string longer
than 4Gb characters even on a 64-bit machine; but if you did, the code would
break.

David Crocker
 
R

Ron Natalie

tings said:
for (int i=0;i < strlen(pathcmd);i++){//this line cause a warning

warning C4018: '<' : signed/unsigned mismatch

strlen returns a number of type 'size_t'. size_t is an unsigned type and
you are comparing it to an int, a signed type.

Two solutions to remove the warning:

1. Change the type of the variable 'i' to 'size_t'.
2. staic_cast i to "unsigned" type.

Which way is better in C++?
I'd use an unsigned (or size_t) variable for i.

However, I wouldn't write the above anyhow. You are computing
strlen(pathcmd) over and over again. Depending what you are
doing with the rest of the loop, there are better ways to count
than that...
 
K

KTC

(2) is much better. Mixing up 'int' and 'size_t' is a sure way
to write non-portable code. For example, for most 64-bit C++
compilers, size_t is 64 bits whereas int is 32 bits. It's
unlikely you would have a string longer than 4Gb characters even
on a 64-bit machine; but if you did, the code would break.

David Crocker

erm, then why are you recommending casting an int?? Or is that a
typo?

KTC
 
M

Mike Wahler

KTC said:
erm, then why are you recommending casting an int??

He's recommending to cast the int to an unsigned type,
so that it can be safely compared against another unsigned
object.
Or is that a
typo?

I don't think so.

-Mike
 
I

Ioannis Vranos

tings said:
for (int i=0;i < strlen(pathcmd);i++){//this line cause a warning

warning C4018: '<' : signed/unsigned mismatch

strlen returns a number of type 'size_t'. size_t is an unsigned type and
you are comparing it to an int, a signed type.

Two solutions to remove the warning:

1. Change the type of the variable 'i' to 'size_t'.
2. staic_cast i to "unsigned" type.

Which way is better in C++?



size_t. Since strlen() returns size_t which usually fits larger positive
integer values, why using int for i?
 
K

KTC

Mike Wahler said:
He's recommending to cast the int to an unsigned type,
so that it can be safely compared against another unsigned
object.


I don't think so.

-Mike

Hmmm, okay. If one's worrying about the possible implementation's
size difference of the different types, then shouldn't one be
recommending to use the same type rather than cast? Namely, size_t
in this case...

Just wondering.

KTC
 
M

Mike Wahler

KTC said:
Hmmm, okay. If one's worrying about the possible implementation's
size difference of the different types, then shouldn't one be
recommending to use the same type rather than cast? Namely, size_t
in this case...

Yes, that's imo the best solution. But as long as the values
being used fit in the actual type being used ('int' in this
case), the cast will do the trick.

-Mike
 
I

Ioannis Vranos

KTC said:
Hmmm, okay. If one's worrying about the possible implementation's
size difference of the different types, then shouldn't one be
recommending to use the same type rather than cast? Namely, size_t
in this case...

Just wondering.


Don't let those guys to confuse you. They just want to look cool. :)


Use size_t.
 

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,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top