Thread overview
DMD: Why bytes, etc. are promoted to ints (if not D linkage)
Mar 14, 2020
Luhrel
Mar 14, 2020
Adam D. Ruppe
Mar 14, 2020
Luhrel
March 14, 2020
Related to: https://issues.dlang.org/show_bug.cgi?id=20644

src/dmd/expressionsem.d: 2081
---
if (tf.linkage != LINK.d)
{
    // Promote bytes, words, etc., to ints
    arg = integralPromotions(arg, sc);
---

What was to purpose of this line ?

Was there some incompatibilities between a C byte and a D byte (or short, or whatever) ?


March 14, 2020
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.
March 14, 2020
On Saturday, 14 March 2020 at 15:50:53 UTC, Adam D. Ruppe wrote:
> 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.
>
> [...]
>

Oh ok. Nice to know.