www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DMD: Why bytes, etc. are promoted to ints (if not D linkage)

reply Luhrel <lucien.perregaux gmail.com> writes:
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) ?
Mar 14
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Mar 14
parent Luhrel <lucien.perregaux gmail.com> writes:
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.
Mar 14