5

Working on this little piece of code in VS2013, but for some reason it doesn't print.it seems that -1>strlen(str)

Anyone got an idea what i'm doing wrong

char *str="abcd";
if(-1<strlen(str))
printf("The size of the string is %d", strlen(str));    
return 0;
Tj L
  • 69
  • 5
  • 1
    what is the output value of `strlen(str)`? – saurabh May 18 '15 at 05:14
  • 1
    Could be that it returns unsigned value and that breaks things – Sami Kuhmonen May 18 '15 at 05:14
  • 2
    it is good to turn on warnings to max settings on your compiler – AndersK May 18 '15 at 05:17
  • It's because of type promotion ans the so-called wraparound. -1 gets promoted to `size_t` and becomes `SIZE_MAX` –  May 18 '15 at 05:23
  • 3
    The reason _why_ it's doing it (integer promotions and the usual arithmetic conversions) is irrelevant. This is clearly a programmer problem since you should never expect -1 to be greater than or equal to the length of _any_ string. If you do silly things, you've got to account for the possibility that you may seem (supposedly) strange results. – paxdiablo May 18 '15 at 05:25
  • [Arithmetic operations on unsigned and signed integers](http://stackoverflow.com/q/2084949/995714) – phuclv May 18 '15 at 05:30
  • Compiling with warnings enabled, such as with `gcc -Wall -W -Werror` would catch this error. Mixing signed and unsigned numbers in comparisons is highly error prone. – chqrlie May 18 '15 at 05:53

3 Answers3

10

Anyone got an idea what i'm doing wrong

strlen() returns a size_t, which is an unsigned integer type. -1 interpreted as an unsigned integer is a large value, so it ends up being greater than the length of your string. You can use the -Wsign-compare flag in gcc and some other compilers to warn you when you try to compare signed and unsigned values.

Also, it doesn't make much sense to compare the length of a string to -1. A length can never be negative; it's always going to be 0 or greater. So you'll probably want to rewrite your code to test against 0, or otherwise properly implement whatever condition you're trying to test for.

if(-1<strlen(str)) printf("The size of the string is %d", strlen(str));

In this code, you might reasonably expect the test to always succeed and the printf() to execute, since the length is always 0 or more. But you're finding that the test actually fails and the printf() never happens because -1 is promoted to an unsigned so that it can be compared to a size_t. The easy solution is to remove the condition altogether: you know the test will always succeed, so there's no need for it. Just remove the if*:

printf("The size of the string is %zu", strlen(str));

*Also, change the print format specifier from %d to %zu since, as Matt McNabb pointed out in a comment, you're trying to print a size_t.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • 1
    You could tell the OP about compiler warnings that, if enabled, prevent this kind of mistake. – chqrlie May 18 '15 at 05:54
4

strlen(str) returns an unsigned integer. When comparing signed integer with unsigned integer, the compiler converts the signed value to unsigned. When converted to unsigned, -1 becomes 2^32 - 1 (assuming that strlen returns a 32 bit integer), which is greater than the length of the string you are comparing with.

Rafi Kamal
  • 4,522
  • 8
  • 36
  • 50
4

strlen returns a value of type size_t. This is an unsigned integral type.

The rule in C for when comparing a signed value with a value of the corresponding unsigned type, is that the signed value is converted to the unsigned value.

If the values are of different sized types, for example if your system has 4-byte int and 8-byte size_t, then the rule is that the value of smaller type is converted to the value of the larger type.

Either way this means that -1 is converted to size_t, resulting in SIZE_MAX which is a large positive value. (unsigned types cannot hold negative values).

This large positive value is greater than the length of your string, so the less-than comparison returns false.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
M.M
  • 138,810
  • 21
  • 208
  • 365
  • You could tell the OP about compiler warnings that, if enabled, prevent this kind of mistake. – chqrlie May 18 '15 at 05:54
  • @chqrlie depends on quality of compiler and settings. I tend to disable signed-unsigned warning as they are false positives more often than not. – M.M May 18 '15 at 05:56