Search code examples
cif-statementstrlen

if statement selects the wrong condition


I have a problem with this code: I don't know why it prints B and not A, since the condition is true. strlen(x) is clearly greater than i. Can you help me?

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

int main()
{
   char x[]="Hello";
   int i = -3;
   
   if(strlen(x)>i)
   {
       printf("A");
   }
   else
   {
       printf("B");
   }
    return 0;
}

Solution

  • The standard function strlen is declared like

    size_t strlen(const char *s);
    

    where the type size_t is an implementation defined unsigned integer type the rank of which is not less than the rank of the type int. Usually the type size_t is defined as an alias for the type unsigned long.

    In the expression used as a condition of the if statement

    if(strlen(x)>i)
    

    the compiler determines the common type of operands using the usual arithmetic conversions. That is the operand i is converted to the type size_t by propagating the sign bit. And as a result the value of the converted operand is a very big unsigned integer of the type size_t that is greater than the returned value of the call of strlen. So the condition evaluates to the logical false.

    Here is a demonstrative program.

    #include <stdio.h>
    
    int main(void) 
    {
        int i = -3;
        
        printf( "( size_t )i = %zu\n", ( size_t )i );
        
        return 0;
    }
    

    Its output might look like

    ( size_t )i = 18446744073709551613
    

    If you want to get the expected by you result in your program you should write

    if( ( int )strlen(x)>i)
    

    or for example

    if( ( long int )strlen(x)>i)
    

    That is you need to cast the value returned by the function strlen to some signed integer type.