Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why implicit conversion occurs for addition between unsigned char?

GCC warns this code:

unsigned char i = 1;
unsigned char j = 2;
i += j;

says:

warning: conversion to 'unsigned char' from 'int' may alter its value [-Wconversion]
   i += j;
        ^

It seems that j is implicitly converted to int.
Why the implicit conversion occurs for the addition of same-type variables?

like image 271
equal-l2 Avatar asked Oct 17 '25 17:10

equal-l2


2 Answers

Here's what the C11 draft standard says about (almost) this very case in §5.1.2.3 (page 15):

EXAMPLE 2

In executing the fragment

char c1, c2;
/* ... */
c1 = c1 + c2;

the ‘‘integer promotions’’ require that the abstract machine promote the value of each variable to int size and then add the two ints and truncate the sum. Provided the addition of two chars can be done without §5.1.2.3 Environment 15 ISO/IEC 9899:201x Committee Draft — April 12, 2011 N1570 overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions.

So, it's done since the standard requires that it is done. If you look the generated code, it's quite (very) possible that the compiler is clever enough not to do the conversion at all in practice.

like image 143
unwind Avatar answered Oct 19 '25 06:10

unwind


C mandates integer promotions, quoting C11 N1570/6.3.1.1p2

The following may be used in an expression wherever an int or unsigned int may be used:

  • An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int

So your unsigned char variable is used in such an expression and as such is converted to int, since i += j is functionally equivalent to i = i + j.

If you know for certain the result is in the range of an unsigned char, then just apply a cast to the result of the addition before assigning, like this:

i = (unsigned char)(i + j)
like image 38
StoryTeller - Unslander Monica Avatar answered Oct 19 '25 06:10

StoryTeller - Unslander Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!