public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* does it matter how I construct an aggregate struct type if its size is the same?
@ 2015-12-18  6:47 Hayden Livingston
  2015-12-18  6:50 ` Hayden Livingston
  2015-12-18 11:08 ` Andrew Haley
  0 siblings, 2 replies; 9+ messages in thread
From: Hayden Livingston @ 2015-12-18  6:47 UTC (permalink / raw)
  To: libffi-discuss

This may be a fundamental question, but does it matter how a struct is
constructed if its size is accurate to the receiving function? That is
if it was made up of all int8s vs. a combination of other types?

My scenario is that I have a receiving function whose actual struct
type information I do not know, but I know its size, so I was thinking
I could just build it up using int8 ffi_type and hope for the best.

Is this correct in the most popular ABIs (x86, x64, arm -
windows/Linux/macosx) that all the ABI and compilers that generate
code respecting those ABI care only about size and alignment?

I suspect so, but I'm not sure if there are quirks? Maybe on Windows?

Thanks!

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: does it matter how I construct an aggregate struct type if its size is the same?
  2015-12-18  6:47 does it matter how I construct an aggregate struct type if its size is the same? Hayden Livingston
@ 2015-12-18  6:50 ` Hayden Livingston
  2015-12-18 11:08 ` Andrew Haley
  1 sibling, 0 replies; 9+ messages in thread
From: Hayden Livingston @ 2015-12-18  6:50 UTC (permalink / raw)
  To: libffi-discuss

I understand that this maybe a systems programming general question
that is not specific to libffi, but I'm asking here since I know some
of you will know this and of course I'm using libffi.

On Thu, Dec 17, 2015 at 10:46 PM, Hayden Livingston
<halivingston@gmail.com> wrote:
> This may be a fundamental question, but does it matter how a struct is
> constructed if its size is accurate to the receiving function? That is
> if it was made up of all int8s vs. a combination of other types?
>
> My scenario is that I have a receiving function whose actual struct
> type information I do not know, but I know its size, so I was thinking
> I could just build it up using int8 ffi_type and hope for the best.
>
> Is this correct in the most popular ABIs (x86, x64, arm -
> windows/Linux/macosx) that all the ABI and compilers that generate
> code respecting those ABI care only about size and alignment?
>
> I suspect so, but I'm not sure if there are quirks? Maybe on Windows?
>
> Thanks!

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: does it matter how I construct an aggregate struct type if its size is the same?
  2015-12-18  6:47 does it matter how I construct an aggregate struct type if its size is the same? Hayden Livingston
  2015-12-18  6:50 ` Hayden Livingston
@ 2015-12-18 11:08 ` Andrew Haley
  2015-12-18 15:16   ` Hayden Livingston
  1 sibling, 1 reply; 9+ messages in thread
From: Andrew Haley @ 2015-12-18 11:08 UTC (permalink / raw)
  To: libffi-discuss

On 18/12/15 06:46, Hayden Livingston wrote:
> This may be a fundamental question, but does it matter how a struct is
> constructed if its size is accurate to the receiving function? That is
> if it was made up of all int8s vs. a combination of other types?

Yes, it does.  But there is a specific exception for character types:
a character type is permitted to alias all other types.  So it's
always safe to use an array of char, say, to hold anything.  (Without
this rule, malloc() would not work.)

Andrew.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: does it matter how I construct an aggregate struct type if its size is the same?
  2015-12-18 11:08 ` Andrew Haley
@ 2015-12-18 15:16   ` Hayden Livingston
  2015-12-18 20:04     ` Andrew Haley
  0 siblings, 1 reply; 9+ messages in thread
From: Hayden Livingston @ 2015-12-18 15:16 UTC (permalink / raw)
  To: Andrew Haley; +Cc: libffi-discuss

Thanks, Andrew. Where is this exception? In ABIs?

So you're suggesting I use char's to construct my ffi_types?

On Fri, Dec 18, 2015 at 3:08 AM, Andrew Haley <aph@redhat.com> wrote:
> On 18/12/15 06:46, Hayden Livingston wrote:
>> This may be a fundamental question, but does it matter how a struct is
>> constructed if its size is accurate to the receiving function? That is
>> if it was made up of all int8s vs. a combination of other types?
>
> Yes, it does.  But there is a specific exception for character types:
> a character type is permitted to alias all other types.  So it's
> always safe to use an array of char, say, to hold anything.  (Without
> this rule, malloc() would not work.)
>
> Andrew.
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: does it matter how I construct an aggregate struct type if its size is the same?
  2015-12-18 15:16   ` Hayden Livingston
@ 2015-12-18 20:04     ` Andrew Haley
  2015-12-18 21:42       ` Jay
  0 siblings, 1 reply; 9+ messages in thread
From: Andrew Haley @ 2015-12-18 20:04 UTC (permalink / raw)
  To: Hayden Livingston; +Cc: libffi-discuss

On 18/12/15 15:16, Hayden Livingston wrote:
> Thanks, Andrew. Where is this exception? In ABIs?
> 
> So you're suggesting I use char's to construct my ffi_types?

Well, it can be awkward.  Some targets pass the components of a
struct in registers.  But this only matters if you pass a struct
by value, which is a fairly unusual thing to do in C.  If you're
passing a struct by reference, then yes, you can just create a
char array of the right size.

Andrew.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: does it matter how I construct an aggregate struct type if its size is the same?
  2015-12-18 20:04     ` Andrew Haley
@ 2015-12-18 21:42       ` Jay
  2015-12-18 22:16         ` Hayden Livingston
  0 siblings, 1 reply; 9+ messages in thread
From: Jay @ 2015-12-18 21:42 UTC (permalink / raw)
  To: Andrew Haley; +Cc: Hayden Livingston, libffi-discuss

Still beware of alignment.

 - Jay

On Dec 18, 2015, at 12:04 PM, Andrew Haley <aph@redhat.com> wrote:

> On 18/12/15 15:16, Hayden Livingston wrote:
>> Thanks, Andrew. Where is this exception? In ABIs?
>> 
>> So you're suggesting I use char's to construct my ffi_types?
> 
> Well, it can be awkward.  Some targets pass the components of a
> struct in registers.  But this only matters if you pass a struct
> by value, which is a fairly unusual thing to do in C.  If you're
> passing a struct by reference, then yes, you can just create a
> char array of the right size.
> 
> Andrew.
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: does it matter how I construct an aggregate struct type if its size is the same?
  2015-12-18 21:42       ` Jay
@ 2015-12-18 22:16         ` Hayden Livingston
  2015-12-18 22:24           ` Andrew Haley
  0 siblings, 1 reply; 9+ messages in thread
From: Hayden Livingston @ 2015-12-18 22:16 UTC (permalink / raw)
  To: Jay; +Cc: Andrew Haley, libffi-discuss

Sorry, I should have been clearer -- I'm absolutely talking about
passing by value. But isn't it on a per argument basis and on its
size? If you have a data structure that is 9 bytes, after alignment
let's say it's 12, isn't that all that matters?

I mean I'm new to this but it seems that if you have a function
compiled by compiler 1, and let's say it is "exported", i.e. some body
else can call into this code via dlopen/loadlibrary you can't
arbitrarily decide how things should be passed right? It has to be on
an ABI-level, and the ABI I'm guessing says parameter 1 if it's size <
X can be passed on the stack, or use some registers, but does an ABI
also specify that struct member 1 if is less than X size can be passed
in register?

This would mean you have to use only 1 compiler.

While typing this email, a thought occurred to me that probably we
programmers know this, and therefore never make our public
dlopen/loadlibrary APIs take structs that are not completely opaque?

Sorry I'm formulating some of my thoughts .. but I'm new to this.

On Fri, Dec 18, 2015 at 1:42 PM, Jay <jay.krell@cornell.edu> wrote:
> Still beware of alignment.
>
>  - Jay
>
> On Dec 18, 2015, at 12:04 PM, Andrew Haley <aph@redhat.com> wrote:
>
>> On 18/12/15 15:16, Hayden Livingston wrote:
>>> Thanks, Andrew. Where is this exception? In ABIs?
>>>
>>> So you're suggesting I use char's to construct my ffi_types?
>>
>> Well, it can be awkward.  Some targets pass the components of a
>> struct in registers.  But this only matters if you pass a struct
>> by value, which is a fairly unusual thing to do in C.  If you're
>> passing a struct by reference, then yes, you can just create a
>> char array of the right size.
>>
>> Andrew.
>>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: does it matter how I construct an aggregate struct type if its size is the same?
  2015-12-18 22:16         ` Hayden Livingston
@ 2015-12-18 22:24           ` Andrew Haley
  2015-12-18 23:10             ` Hayden Livingston
  0 siblings, 1 reply; 9+ messages in thread
From: Andrew Haley @ 2015-12-18 22:24 UTC (permalink / raw)
  To: libffi-discuss

On 18/12/15 22:15, Hayden Livingston wrote:
> Sorry, I should have been clearer -- I'm absolutely talking about
> passing by value. But isn't it on a per argument basis and on its
> size? If you have a data structure that is 9 bytes, after alignment
> let's say it's 12, isn't that all that matters?

No.

> I mean I'm new to this but it seems that if you have a function
> compiled by compiler 1, and let's say it is "exported", i.e. some body
> else can call into this code via dlopen/loadlibrary you can't
> arbitrarily decide how things should be passed right? It has to be on
> an ABI-level, and the ABI I'm guessing says parameter 1 if it's size <
> X can be passed on the stack, or use some registers, but does an ABI
> also specify that struct member 1 if is less than X size can be passed
> in register?

Yes, it often does exactly that.  So if you have an arg which is 2
ints then the 2 ints get passed in 2 registers.  Float members get
passed in float registers, etc.  These days that's the way things are
usually done, with some exceptions such as legacy 32-bit x86.

The ABI really does need to know what is inside the struct.

> This would mean you have to use only 1 compiler.

Huh?  Its the ABI.

> While typing this email, a thought occurred to me that probably we
> programmers know this, and therefore never make our public
> dlopen/loadlibrary APIs take structs that are not completely opaque?
> 
> Sorry I'm formulating some of my thoughts .. but I'm new to this.

Fair enough.

Andrew.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: does it matter how I construct an aggregate struct type if its size is the same?
  2015-12-18 22:24           ` Andrew Haley
@ 2015-12-18 23:10             ` Hayden Livingston
  0 siblings, 0 replies; 9+ messages in thread
From: Hayden Livingston @ 2015-12-18 23:10 UTC (permalink / raw)
  To: Andrew Haley; +Cc: libffi-discuss

Thanks for this, Andrew. I've now read up a bit more and can safely
say that I agree with you AND understand it.

Also realizing that intricacies of compiler differences and ABI issues
that people often prefer to keep their public APIs are pointer size or
less.

On Fri, Dec 18, 2015 at 2:24 PM, Andrew Haley <aph@redhat.com> wrote:
> On 18/12/15 22:15, Hayden Livingston wrote:
>> Sorry, I should have been clearer -- I'm absolutely talking about
>> passing by value. But isn't it on a per argument basis and on its
>> size? If you have a data structure that is 9 bytes, after alignment
>> let's say it's 12, isn't that all that matters?
>
> No.
>
>> I mean I'm new to this but it seems that if you have a function
>> compiled by compiler 1, and let's say it is "exported", i.e. some body
>> else can call into this code via dlopen/loadlibrary you can't
>> arbitrarily decide how things should be passed right? It has to be on
>> an ABI-level, and the ABI I'm guessing says parameter 1 if it's size <
>> X can be passed on the stack, or use some registers, but does an ABI
>> also specify that struct member 1 if is less than X size can be passed
>> in register?
>
> Yes, it often does exactly that.  So if you have an arg which is 2
> ints then the 2 ints get passed in 2 registers.  Float members get
> passed in float registers, etc.  These days that's the way things are
> usually done, with some exceptions such as legacy 32-bit x86.
>
> The ABI really does need to know what is inside the struct.
>
>> This would mean you have to use only 1 compiler.
>
> Huh?  Its the ABI.
>
>> While typing this email, a thought occurred to me that probably we
>> programmers know this, and therefore never make our public
>> dlopen/loadlibrary APIs take structs that are not completely opaque?
>>
>> Sorry I'm formulating some of my thoughts .. but I'm new to this.
>
> Fair enough.
>
> Andrew.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-12-18 23:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-18  6:47 does it matter how I construct an aggregate struct type if its size is the same? Hayden Livingston
2015-12-18  6:50 ` Hayden Livingston
2015-12-18 11:08 ` Andrew Haley
2015-12-18 15:16   ` Hayden Livingston
2015-12-18 20:04     ` Andrew Haley
2015-12-18 21:42       ` Jay
2015-12-18 22:16         ` Hayden Livingston
2015-12-18 22:24           ` Andrew Haley
2015-12-18 23:10             ` Hayden Livingston

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).