4.7k views

Consider the following C program.

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

void printlength(char *s, char *t) {
unsigned int c=0;
int len = ((strlen(s) - strlen(t)) > c) ? strlen(s) : strlen(t);
printf("%d\n", len);
}

void main() {
char *x = "abc";
char *y = "defgh";
printlength(x,y);
}

Recall that $strlen$ is defined in $string.h$ as returning a value of type $size\_t$, which is an unsigned int. The output of the program is __________ .

edited | 4.7k views

Let us assume our int  is of 3 bits then

value of binary 110  in unsigned int will be 6.( which is > 0)

value of binary 110  in signed int (or int ) will be -2. (In C int is represented in  2's compliment  representation)

One more thing -->

As you can see, (unsigned)0 - (unsigned)1 equals -1 modulo UINT_MAX+1, or in other words, UINT_MAX.

$(strlen(s)- strlen(t)) = 3-5 =-2$

But in C, when we do operation with two unsigned integers, result is also unsigned. ($strlen$ returns $size\_t$ which is unsigned in most systems). So, this result "$-2$" is treated as unsigned and its value is $INT\_MAX - 2$ (not sure about all systems, but at least on systems using $2$'s complement representation). Now, the comparison is between this large number and another unsigned number $c$ which is $0$. So, the comparison return TRUE here.

Even if '$c$' is declared as "$int$", while doing an operation with an unsigned int, it gets promoted to unsigned int and we get the same result.

Hence $(strlen(s)- strlen(t)) >0$ will return $1$ on execution thus the conditional operator will return the true statement which is $strlen(abc) =3$.

Ans should be $3$.
edited by
The Answer is 3 but I found somewhat a different explanation.
Even if 'unsigned int c' is not given, ((strlen (s) - strlen (t)) > c) would return true(and print 3 as output) since strlen() function always returns unsigned value. So, strlen(s) - strlen(t) will yield unsigned-unsigned= unsigned value which, upon being compared with c( even if it is signed), would return TRUE( and print 3 ) since c will be converted to unsigned.

So, having unsigned/siged int c doesn't make much of a dfference.
You are correct.

the definition of strlen function is given in string.h header file and the output of the strlen function retrun a value of type size_t form and size_t is a unsigned integer . so in each case  ((strlen(s) - strlen(t)) > c) return a unsigned value, it is not matter that whether c is given unsigned or not.

if c is not given unsgined then answer also will be same .

Binary operations between different integral types are performed within a "common" type defined by so called usual arithmetic conversions (see the language specification, 6.3.1.8)

C Language Specification URL : www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

So here (strlen(s)-strlen(t)) which is coming as -2 is converted to first unsigned int (which evaluates to INT_MAX-2) and then it is compared with c(c being unsigned int) which is 0.

The result of the boolean expression in program goes true and strlen(s) is selected for output which prints output as 3.

IIn above case it returns -2 .I think it should return 2 .Do not understand why this is happening .We discussed that arithmetic calcuation between unsigned is always positive.

size_t strlen( const char *s );

Thanx that was an eye opener

Here, we compare length of pointer because s and t are char type pointer. But all type of pointer have same size then why we get length of string and when i try to print strlen(*y) i got error . why?

could you explain ?

@gaurav456

You should try this code. You were printing with %d which converts c to signed integer. So pick %ld which is big enough to take the large unsigned value that c has.

#include<stdio.h>
void main()
{

unsigned int a=3, b=5,c;
c=a-b;
long d=c;
printf("%ld",d);

}
ToBONGBIRDIE .. i appreciate your information regarding strlen() but I have a doubt ..

you said "strlen(s) - strlen(t) will yield unsigned-unsigned= unsigned".

Now  strlen(s) & strlen(t) produces separately positive values 3 and 5 respectively. Now as both 3 & 5 are unsigned... so (3-5) is not resulting (-2) ?

If it resulting (-2) then how that "unsigned int c" does not matter in the question?

@Arjun sir

Shouldn't it be

-2 mod (INT_MAX +1) = INT_MAX - 1 and   NOT INT_MA X - 2 , Considering 2's complement representation.

Suppose  numbes are represented in 2's complement.

Then ,(strlen(s)- strlen(t)) gives -2.

Because it is unsigned ,its binary format will be in 2's complement

+2n-1-2 on n bit machine.

Just care here about that it will be positive and  condition become true,and length of first string gets printed which is 3.

This is because of the unsigned int property which causes negative values to overflow into a large positive number
see this code snippet for better understanding

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

void printlength(char *s, char *t) {
unsigned int c = 0;
int len = ((strlen(s) - strlen(t)) > c )? strlen(s) : strlen(t);
printf("using standard int = %d\n", (strlen(s) - strlen(t)));
printf("using unsigned int = %u\n", (strlen(s) - strlen(t)));
printf("%d\n", len);
}

void main() {
char *x = "abc";
char *y = "defgh";
printlength(x,y);
}
–1 vote
5 is the answer because ((3-5)>0 ) return 0 so len=strlen(t).

#include<stdio.h>
int main(){
printf("%d\n",((3-5)>0));
return 0;
}

[email protected]:~/socket_programming$gcc compare.c [email protected]:~/socket_programming$ ./a.out
0
Good, but what you just answered showed a different thing - integer constants by default is signed in C.