3
char a;
char b;
char c;

a = b + c;

a = (char)((int)b+(int)c);

In the first line it's implict conversion from char to int. In the second line it's explicit. Is there a difference in the binary file generated by compiler?

Please consider this question from embedded systems perspective.

bubble
  • 3,408
  • 5
  • 29
  • 51

4 Answers4

5

With my compiler it produces the exact same assembly twice:

 4: 0f b6 55 ff             movzbl -0x1(%rbp),%edx
 8: 0f b6 45 fe             movzbl -0x2(%rbp),%eax
 c: 01 d0                   add    %edx,%eax
 e: 88 45 fd                mov    %al,-0x3(%rbp)

11: 0f b6 55 ff             movzbl -0x1(%rbp),%edx
15: 0f b6 45 fe             movzbl -0x2(%rbp),%eax
19: 01 d0                   add    %edx,%eax
1b: 88 45 fd                mov    %al,-0x3(%rbp)

As you see, this is AMD64 assembly (produced by GCC 4.6.2). The only way to be sure is to compile it for your target platform and check the assembly.

Niklas B.
  • 92,950
  • 18
  • 194
  • 224
  • 2
    Are your `char`s signed or unsigned? Does it matter? – Adam Liss Mar 05 '12 at 17:25
  • @Adam: It's the code from the question, so neither signed nor unsigned, just `char`. However, the result is exactly the same with `unsigned char` or `signed char`. – Niklas B. Mar 05 '12 at 17:27
  • @Benoit: This might be correct in the case of GCC, I don't know. I don't [think this is defined by the standard](http://stackoverflow.com/questions/2054939/char-is-signed-or-unsigned-by-default), though. – Niklas B. Mar 05 '12 at 17:28
  • 1
    @Benoit the "default" depends on the system – sidyll Mar 05 '12 at 17:28
4

My reading of the standard suggests that this is left up to the implementation and the optimizer.

Section 5.1.2.3, part 10:

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 overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions.

My understanding is that the standard lets the compiler decide if it is OK to use 8-bit addition, as long as the result is not going to be distinguishable from the addition of ints and converted to chars.

NOTE Back at my days in the embedded world (mid-nineties), the C compiler that we used for our 8-bit platforms, Whitesmith compiler for 68HC11, produced a "plain" 8-bit addition instruction for adding two chars. The only way to find out for sure what happens in your fujitsu system would be to compile-to-assembly and check for yourself.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

Per the C standard the result must be the same, embedded or not.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
1

Both expression statements (1) and (2) are equivalent.

char a;
char b;
char c;

a = b + c;   // (1)

a = (char)((int)b+(int)c);  // (2)

By the rules of the usual arithmetic conversions, b and c are both converted to int (integer promotion). Then b + c is converted to char by the semantics of the assignment operator.

Additive operators:

(C99, 6.5.6p4) "If both operands have arithmetic type, the usual arithmetic conversions are performed on them."

Simple assignment:

(C99, 6.5.16.1p2 Assignment) "In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand".

Integer promotions:

(C99, 6.3.1.1p2) "if an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions."

ouah
  • 142,963
  • 15
  • 272
  • 331