Thread overview
Why is the ABI for structs different between Linux and Windows?
May 16, 2008
Don
May 17, 2008
Walter Bright
May 17, 2008
Robert Fraser
May 17, 2008
Walter Bright
May 17, 2008
Robert Fraser
May 17, 2008
Walter Bright
May 17, 2008
Robert Fraser
May 26, 2008
Don
May 16, 2008
From the ABI page, there are 2 ABI differences between Windows and Linux. One is the amount of padding after a 'real'. That's understandable, because it's imposed by the OS. But the second difference relates to structs, and is non-obvious:

# For Windows, 1, 2 and 4 byte structs are returned in EAX.
# For Windows, 8 byte structs are returned in EDX,EAX, where EDX gets the most significant half.
# For other struct sizes, and for all structs on Linux, the return value is stored through a hidden pointer passed as an argument to the function.

Why the difference between Windows & Linux? Is there a good technical reason for it? Or is it a quirk that we might be able to get rid of eventually?

It particularly looks like a quirk because the section on parameters states:

#The last parameter is passed in EAX rather than being pushed on the stack if the following conditions are met:

    * It fits in EAX.
    * It is not a 3 byte struct.

which sounds as if 1,2 and 4 byte structs are placed in EAX for parameters, but not return values.

If it is a quirk that may be removed, I suggest an extra sentence:

# For other struct sizes, and for all structs on Linux, the return value is stored through a hidden pointer passed as an argument to the function. In the future, 1, 2, 4, and 8 byte structs on Linux may be returned using the same calling convention as for Windows.



May 17, 2008
The struct ABI is designed to be compatible with the C struct behavior for the local C compiler.
May 17, 2008
Walter Bright wrote:
> The struct ABI is designed to be compatible with the C struct behavior for the local C compiler.

Is it possible to just use this behavior for extern(C) structs while structs with D linkage use the Windows behavior on Linux, too?
May 17, 2008
Robert Fraser wrote:
> Walter Bright wrote:
>> The struct ABI is designed to be compatible with the C struct behavior for the local C compiler.
> 
> Is it possible to just use this behavior for extern(C) structs while structs with D linkage use the Windows behavior on Linux, too?

Why do that? You can control the layout with the align attribute, if need be.
May 17, 2008
Walter Bright wrote:
> Robert Fraser wrote:
>> Walter Bright wrote:
>>> The struct ABI is designed to be compatible with the C struct behavior for the local C compiler.
>>
>> Is it possible to just use this behavior for extern(C) structs while structs with D linkage use the Windows behavior on Linux, too?
> 
> Why do that? You can control the layout with the align attribute, if need be.

How would that allow an 8-byte struct to be passed in registers on Linux?
May 17, 2008
Robert Fraser wrote:
> Walter Bright wrote:
>> Robert Fraser wrote:
>>> Walter Bright wrote:
>>>> The struct ABI is designed to be compatible with the C struct behavior for the local C compiler.
>>>
>>> Is it possible to just use this behavior for extern(C) structs while structs with D linkage use the Windows behavior on Linux, too?
>>
>> Why do that? You can control the layout with the align attribute, if need be.
> 
> How would that allow an 8-byte struct to be passed in registers on Linux?

You can do that now if you use the D function calling convention. Using extern(C) gives you the C calling convention.
May 17, 2008
Walter Bright wrote:
> Robert Fraser wrote:
>> Walter Bright wrote:
>>> Robert Fraser wrote:
>>>> Walter Bright wrote:
>>>>> The struct ABI is designed to be compatible with the C struct behavior for the local C compiler.
>>>>
>>>> Is it possible to just use this behavior for extern(C) structs while structs with D linkage use the Windows behavior on Linux, too?
>>>
>>> Why do that? You can control the layout with the align attribute, if need be.
>>
>> How would that allow an 8-byte struct to be passed in registers on Linux?
> 
> You can do that now if you use the D function calling convention. Using extern(C) gives you the C calling convention.

*returned... Don's original question that started the topic.
May 26, 2008
Walter Bright wrote:
> The struct ABI is designed to be compatible with the C struct behavior for the local C compiler.

That's clear enough for extern(C) ... but why does it need to be that way for extern(D) ? (or internal D functions, for that matter).

Why not take the opportunity to standardize the D calling convention for a single CPU?