0
#include <stdio.h>
#include <string.h>

int main()
{
    const char str[11]= "Hello World";
    if(-1 > strlen(str)){
        printf(str);
    }

    return 0;
}

This if condition should always return false. But here it's not. But if I put strlen(str) value to another variable and compare with that, then it works as expected. What I am missing here? Is it compiler dependent or something?

codersaif
  • 946
  • 9
  • 15
  • `printf(str)`...hmmmm. – Sourav Ghosh Jun 12 '20 at 12:57
  • 11
    Your `str` is not null terminated, since you didn't leave enough space for the null. So calling `strlen` on it runs off the end, which causes undefined behavior. Calling `printf` on it is undefined too. – Nate Eldredge Jun 12 '20 at 12:57
  • 7
    Also, bear in mind that `strlen` returns an *unsigned* value (`size_t`). – Adrian Mole Jun 12 '20 at 12:58
  • Change to `const char str[12] = "Hello World"`, or better, `const char str[] = "Hello World"` and let the compiler figure out the size (it will include a terminating null in this case). – Nate Eldredge Jun 12 '20 at 12:58
  • 4
    Turn on compiler warnings `-Wall -Wextra` – klutt Jun 12 '20 at 12:58
  • You are comparing a signed value with an unsigned value. This does not result in a mathematically correct answer. – john Jun 12 '20 at 12:59
  • 1
    Just change it to `if (-1 > static_cast(std::strlen(str))) {`, assuming you fix `str[12]` problem. Or use `std::string`, and make everything easier. – Eljay Jun 12 '20 at 13:07
  • 1
    @Eljay: I prefer the transformation `if (0 > 1 + std::strlen(str))`. 6 of one and 1/2 dozen of the other I guess though. – Bathsheba Jun 12 '20 at 13:07
  • 4
    Evidently a person new to `C` can too easily arouse the wrath of more experienced `C` programmers by simply not looking at compiler warnings, and invoking UB in the example code posted. Or are all the down clicks just mindless pile-it-on? Seriously, the message has been received by now. A little more self-control on the down click trigger finger might be a good idea here. – ryyker Jun 12 '20 at 13:42
  • 4
    @ryyker: Indeed. The question is clear enough to be answerable. There's compilable code in there too, and the actual and expected behaviour is well-documented. – Bathsheba Jun 12 '20 at 13:58
  • 1
    @ryyker, I was using arduino and there was no warnings showing. – codersaif Jun 12 '20 at 13:58
  • Sometimes I see a question that for all appearances would be a very typical one, asked by any new programmer, and when written well enough to to be answered in such a clear way, they are often up clicked as being useful to other new programmers. But then occasionally, for whatever strange reason the mood of the blogosphere is pissy. I think you just happened to post your question on a pissy day. It's a good question. By the way, the suggestion to turn up your compiler warnings in prior comments is a good one. If you have not already done that, look up how in your compiler documentation. – ryyker Jun 12 '20 at 14:13
  • 1
    @Bathsheba - yes I agree. Very well said. Chalk this one up to temporary insanity brought on by those in isolation too long, having to wear little blue masks and not being able to visit with their favorite people. :) – ryyker Jun 12 '20 at 14:19
  • 2
    @ryyker: Indeed. I can't complain as I'm holed up in my large house in the West Country of England. I can't resist plugging my answer here: https://meta.stackexchange.com/questions/303920/winter-bash-2017-counting-down-page-whats-with-the-fence/303921#303921 It's only conjecture but I think voting tends to be more extreme on a Friday: up and down. – Bathsheba Jun 12 '20 at 14:21
  • Since you tagged as C++, you should prefer `std::string` to character arrays. Character arrays can overflow. – Thomas Matthews Jun 12 '20 at 15:15

1 Answers1

18

strlen returns an unsigned type.

That has the effect of converting -1 to an unsigned type, which is a large number.

That number will be greater than the strlen result so program control reaches the if statement body.

If you assign the value of strlen to a variable of signed type, and compare using that, then the conversion of -1 will not occur and the if statement will behave as you expect.


Note that technically the behaviour of your code is undefined, you need 12 elements for that string (for the NUL terminator), not 11, and strlen requires that NUL terminator in order to work properly. It's best to let the compiler do the counting, by writing

const char str[] = "Hello World";
Bathsheba
  • 231,907
  • 34
  • 361
  • 483