| |
| Posted by Adam D. Ruppe in reply to Luhrel | PermalinkReply |
|
Adam D. Ruppe
Posted in reply to Luhrel
| On Saturday, 14 March 2020 at 15:27:50 UTC, Luhrel wrote:
> // Promote bytes, words, etc., to ints
> arg = integralPromotions(arg, sc);
> ---
>
> What was to purpose of this line ?
The C spec requires integers to be promoted to int in such cases. C style variadics will be expecting something of `int` size or larger.
You can printf("%hd", some_short) but C still expects some_short to be promoted to int before passed so it will look at 32 bits on the abi level.
```
#include<stdio.h>
int main() {
short a = 10;
printf("%hd\n", a);
}
```
gcc compiling that will disassemble to:
```
0000000000401112 <main>:
401112: 55 push rbp
401113: 48 89 e5 mov rbp,rsp
401116: 48 83 ec 10 sub rsp,0x10
40111a: 66 c7 45 fe 0a 00 mov WORD PTR [rbp-0x2],0xa
401120: 0f bf 45 fe movsx eax,WORD PTR [rbp-0x2]
401124: 89 c6 mov esi,eax
401126: bf 04 20 40 00 mov edi,0x402004
40112b: b8 00 00 00 00 mov eax,0x0
401130: e8 fb fe ff ff call 401030 <printf@plt>
401135: b8 00 00 00 00 mov eax,0x0
40113a: c9 leave
40113b: c3 ret
40113c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
```
Notice the `movsx eax`, move with sign extension, into a 32 bit register, which is then passed as the argument, despite the variable itself being a 16 bit short. C promotes it too for the variadic, so D must do the same.
|