Lone Learner Lone Learner - 2 months ago 11
C Question

Is a type cast necessary while converting between signed int and unsigned int?

I tried assigning a signed int to unsigned int.

#include <stdio.h>

int main()
{
int a;
unsigned int b;
scanf("%d", &a);
b = a;
printf("%d %u\n", a, b);
return 0;
}


I was hoping that compiling this would cause a warning that I am
assigning an int value to unsigned int variable. But I did not get any
warning.

$ gcc -std=c99 -Wall -Wextra -pedantic foo.c
$ echo -1 | ./a.out
-1 4294967295


Next I tried to assigning an unsigned int to signed int.

#include <stdio.h>

int main()
{
int a;
unsigned int b;
scanf("%u", &b);
a = b;
printf("%d %u\n", a, b);
return 0;
}


Still no warning.

$ gcc -std=c99 -Wall -Wextra -pedantic bar.c
$ echo 4294967295 | ./a.out
-1 4294967295


Two questions:


  1. Why are no warnings generated in these cases even though the input gets
    modified during the conversions?

  2. Is a type cast necessary in either of the cases?


M.M M.M
Answer

Code 1: This conversion is well-defined. If the int is out of range of unsigned int, then UINT_MAX + 1 is added to bring it in range.

Since the code is correct and normal, there should be no warning. However you could try the gcc switch -Wconversion which does produce a warning for some correct conversions, particularly signed-unsigned conversion.

Code 2: This conversion is implementation-defined if the input is larger than INT_MAX. Most likely the implementation you are on defines it to be the inverse of the conversion in Code 1.

Typically, compilers don't warn for implementation-defined code which is well-defined on that implementation. Again you can use -Wconversion.

A cast is not necessary and as a general principle, casts should be avoided as they can hide error messages.

Comments