3 ms·
Does the Arduino really promote two chars to int when performing on them? It is an 8-bit chip, and that would take a number of cycles more, than to just leave
by klingonopera 7y ago
Does the Arduino really promote two chars to int when performing on them?
It is an 8-bit chip, and that would take a number of cycles more, than to just leave them...?
- int_19h 7y agoI'm not sure about Arduino specifically, but 8-bit usually refers to memory bus width, not the register size. IIRC Arduino has 16-bit registers? So I'd expect it to have a 16-bit int. And depending on the exact expression, it doesn't have to actually do anything differently - these integer conversions describe the expected result of the operation, not how it's performed in assembly. So when you write something like this: char a, b, c; ... a = b + c the spec requires that b+c is treated as an int addition, but the resulting int is then assigned to a char variable, which basically truncates it. Furthermore, if b+c is larger than can fit in a char, then we have signed overflow (assuming that char is signed, which is usually the case), which is undefined behavior. Altogether, this means that the compiler can actually do an 8-bit addition here while remaining within the bounds of the spec. OTOH if the result is assigned to an int variable, then yeah, it'd have to promote them - but that would also be far less surprising to you than if it didn't, no? Where this can potentially lead to more overhead than you'd expect is use of the temporary as input to another subexpresion. E.g. suppose we have this: a = (b + c) / 2 Suppose b is 200 and c is 100. The spec requires that the result of this operation is 150, because b+c is performed on ints, and thus won't overflow. If it were an 8-bit addition of signed chars, assuming the typical wraparound behavior on overflow, you'd get 22.
- klingonopera 7y agoWhen referring to the Arduino, unless explicitly stating a specific chip, most people are actually referring to the AT328P chip, which is a chip with 8-bit architecture (registers are 8-bit, 16-bit data types are split between a high and a low register). It has 32 KB programmable memory, and 2 KB RAM. Indeed, though, on the Arduino platform, an int is usually 16 bit, but not because that's the chip's native archticture, but because that's the range required. Though I can't say for sure, I highly doubt (and now am actually almost completely certain in my doubts) that it would promote two chars to ints to perform operations on them, and last night also realized why, namely, there are counts for the number of cycles required to do operations on various data types [0]. If what you say about integer promotion is true, there would be no difference in clock cycles between an int and a byte, but there is. So in essence, no, the Arduino is definitely somehow deviating from spec when it comes to promotion. [0]: https://forum.arduino.cc/index.php?topic=92684.msg696420#msg696420 https://forum.arduino.cc/index.php?topic=92684.msg696420#msg... EDIT: I just realized, I think I need to actually look into the (Atmel's) AVR specs, as the Arduino IDE is basically just a wrapper for that.
- int_19h 7y agoInteresting. Yeah, you're right, int has to be at least 16-bit by the spec. But, again, this would only manifest in expressions where you mix operators, or try to assign the result to a variable of a broader type. So (a+b+c) could still be evaluated entirely in 8 bits without becoming non-conforming, if target is a char, and ditto for (a-b-c) etc. So long as you know that only the last 8 bits of the result is all that matters, the promotion can be disregarded. It's only when you apply some other operator - multiplication, division, bit shift, or comparison - to the intermediate result that you can observe the increased width. But that doesn't actually happen all that often. (Conversely, it might also mean that it is not conforming, but there are relatively few practical cases where it actually manifests.)