L
lovecreatesbeauty
I was reading on c-faq value preserving and unsigned preserving,
though I didn't find much detail discussion about this on K&R2 and
C:ARM5. Some posts quote these two preserving being term in standard
document. Does it mean that it's ok for mediocrity C programmer (eg.
me) to put focus on promotion conversion (converted to lager type) and
narrowing conversion?
The c-faq states that both value and unsigned preserving are for
promotion conversion, but narrowing conversion may happen in value
preserving as well.
There's warning on Ln 36, but none on Ln 31 and 32, why?
Does this trivial code demonstrate most kinds of integer conversion
cases in C? If it doesn't, could you please suggest more situation?
Narrowing conversion may lead to data loseing, so this is the only
dangrous conversion, right?
Thank you for your time.
$ cat a.c
#include <stdio.h>
#include <limits.h>
int main(void)
{
char c = CHAR_MAX;
unsigned char uc = UCHAR_MAX;
short s = SHRT_MAX;
unsigned short us = USHRT_MAX;
int i = INT_MAX;
unsigned int ui = UINT_MAX;
long l = LONG_MAX;
unsigned long ul = ULONG_MAX;
printf("\n");
printf("LIMITS: c:%d, uc:%u, s:%d, us:%u\n"
"LIMITS: i:%d, ui:%u, l:%ld, ul:%lu\n",
c, uc, s, us, i, ui, l, ul);
/* promotion */
printf("\n");
printf("i = s: %d, ", i = s);
printf("i = us: %d, ", i = us);
printf("ui = s: %u, ", ui = s);
printf("ui = us: %u\n", ui = us);
/* narrowing */
printf("\n");
printf("c = s: %d, ", c = s);
printf("c = us: %d, ", c = us);
printf("uc = s: %d, ", uc = s); /*Ln:31*/
printf("uc = us: %d\n", uc = us);
printf("\n");
printf("uc = UCHAR_MAX (%u) + 1: %u, ",
UCHAR_MAX, uc = UCHAR_MAX + 1); /* Ln:36 */
printf("uc = -1: %d\n", uc = -1);
return 0;
}
$ make && ./a.out
gcc -ansi -pedantic -Wall -W -c -o a.o a.c
a.c: In function ‘main’:
a.c:36: warning: large integer implicitly truncated to unsigned type
gcc a.o -o a.out
LIMITS: c:127, uc:255, s:32767, us:65535
LIMITS: i:2147483647, ui:4294967295, l:2147483647, ul:4294967295
i = s: 32767, i = us: 65535, ui = s: 32767, ui = us: 65535
c = s: -1, c = us: -1, uc = s: 255, uc = us: 255
uc = UCHAR_MAX (255) + 1: 0, uc = -1: 255
$
though I didn't find much detail discussion about this on K&R2 and
C:ARM5. Some posts quote these two preserving being term in standard
document. Does it mean that it's ok for mediocrity C programmer (eg.
me) to put focus on promotion conversion (converted to lager type) and
narrowing conversion?
The c-faq states that both value and unsigned preserving are for
promotion conversion, but narrowing conversion may happen in value
preserving as well.
There's warning on Ln 36, but none on Ln 31 and 32, why?
Does this trivial code demonstrate most kinds of integer conversion
cases in C? If it doesn't, could you please suggest more situation?
Narrowing conversion may lead to data loseing, so this is the only
dangrous conversion, right?
Thank you for your time.
$ cat a.c
#include <stdio.h>
#include <limits.h>
int main(void)
{
char c = CHAR_MAX;
unsigned char uc = UCHAR_MAX;
short s = SHRT_MAX;
unsigned short us = USHRT_MAX;
int i = INT_MAX;
unsigned int ui = UINT_MAX;
long l = LONG_MAX;
unsigned long ul = ULONG_MAX;
printf("\n");
printf("LIMITS: c:%d, uc:%u, s:%d, us:%u\n"
"LIMITS: i:%d, ui:%u, l:%ld, ul:%lu\n",
c, uc, s, us, i, ui, l, ul);
/* promotion */
printf("\n");
printf("i = s: %d, ", i = s);
printf("i = us: %d, ", i = us);
printf("ui = s: %u, ", ui = s);
printf("ui = us: %u\n", ui = us);
/* narrowing */
printf("\n");
printf("c = s: %d, ", c = s);
printf("c = us: %d, ", c = us);
printf("uc = s: %d, ", uc = s); /*Ln:31*/
printf("uc = us: %d\n", uc = us);
printf("\n");
printf("uc = UCHAR_MAX (%u) + 1: %u, ",
UCHAR_MAX, uc = UCHAR_MAX + 1); /* Ln:36 */
printf("uc = -1: %d\n", uc = -1);
return 0;
}
$ make && ./a.out
gcc -ansi -pedantic -Wall -W -c -o a.o a.c
a.c: In function ‘main’:
a.c:36: warning: large integer implicitly truncated to unsigned type
gcc a.o -o a.out
LIMITS: c:127, uc:255, s:32767, us:65535
LIMITS: i:2147483647, ui:4294967295, l:2147483647, ul:4294967295
i = s: 32767, i = us: 65535, ui = s: 32767, ui = us: 65535
c = s: -1, c = us: -1, uc = s: 255, uc = us: 255
uc = UCHAR_MAX (255) + 1: 0, uc = -1: 255
$