|
|
@ -2,79 +2,79 @@ |
|
|
|
|
|
|
|
## Explicit Integer Sizes |
|
|
|
|
|
|
|
Last week at fdik's we spoke about mapping IDL type to language types; and we found it desirable to specify explicit |
|
|
|
integer sizes for some languages -- for example Java, that mandates a precise size for int and long. |
|
|
|
Shall we do the same for C and switch to stdint types? I would say not, because it is not in the “culture” of C. |
|
|
|
But, if we want to follow the minimum-common-denominator idea, maybe we should not have any unsigned type. |
|
|
|
I am willing to remove them from the Engine API if we agree on that. |
|
|
|
|
|
|
|
Last week at fdik's we spoke about mapping IDL type to language types; and we found it desirable to specify explicit |
|
|
|
integer sizes for some languages -- for example Java, that mandates a precise size for int and long. |
|
|
|
Shall we do the same for C and switch to stdint types? I would say not, because it is not in the “culture” of C. |
|
|
|
But, if we want to follow the minimum-common-denominator idea, maybe we should not have any unsigned type. |
|
|
|
I am willing to remove them from the Engine API if we agree on that. |
|
|
|
|
|
|
|
## Terminology: Param Passing Mode |
|
|
|
|
|
|
|
fdik is not very happy with the mode names |
|
|
|
And yes, he has a big point |
|
|
|
about them not conveying an explicit idea of ownership. |
|
|
|
Agreed: we can easily rename them later |
|
|
|
fdik is not very happy with the mode names |
|
|
|
And yes, he has a big point |
|
|
|
about them not conveying an explicit idea of ownership. |
|
|
|
Agreed: we can easily rename them later |
|
|
|
|
|
|
|
## Bitmasks |
|
|
|
|
|
|
|
e.g. flags |
|
|
|
Personally I would use unsigned integers only for bit masks -- well, we have them :-) |
|
|
|
Those could be made unsigned, but in practice I think we do not care. We can assume that ints will have at least 31 |
|
|
|
non-sign bits on every configuration |
|
|
|
e.g. flags |
|
|
|
Personally I would use unsigned integers only for bit masks -- well, we have them :-) |
|
|
|
Those could be made unsigned, but in practice I think we do not care. We can assume that ints will have at least 31 |
|
|
|
non-sign bits on every configuration |
|
|
|
|
|
|
|
## Optionals |
|
|
|
|
|
|
|
In C and C++ passing objects by pointers also allows representing NULL values. That is also true in most languages but |
|
|
|
not in all. And I think that we do exploit the NULL case in some functions; certainly for strings. |
|
|
|
Have we got “optional output parameters”? Those are used in C. Something like: if the 2nd parameter is not NULL, the |
|
|
|
function will set the pointed variable to X, otherwise it will ignore it. |
|
|
|
Do we want to remove that from the API? That will be difficult to map in different languages. |
|
|
|
So, in the document we seem to really rely on the possibility of pointers being NULL. Type definitions might be a little |
|
|
|
messiers in languages where that is not allowed by default. Rust is probably one of those. |
|
|
|
I do not really know Rust but know ML and Haskell. To present the problem, this is what they do: |
|
|
|
I can use ML as an example. |
|
|
|
For every type “T” there exists a type “T option”. |
|
|
|
There is no NULL in the language, and no implicit initial value for variables: it is mandated by the syntax that |
|
|
|
variables are initialised. |
|
|
|
So, how do we represent “absent” values? |
|
|
|
“T option” has two kind of values: “Nothing” or “Some V” where V is a value of type T. |
|
|
|
So, we rely on pointers being used both for indirection and for optionality. |
|
|
|
The point is: given a struct definition, we usually want its non-primitively-typed field to be optional. |
|
|
|
That is certainly the case for identities and messages. |
|
|
|
AGREED In theory we should accept that a lot of that work is done “by hand” by the person who writes the adapter, |
|
|
|
because the native type definition is supposed to follow the language culture |
|
|
|
In C and C++ passing objects by pointers also allows representing NULL values. That is also true in most languages but |
|
|
|
not in all. And I think that we do exploit the NULL case in some functions; certainly for strings. |
|
|
|
Have we got “optional output parameters”? Those are used in C. Something like: if the 2nd parameter is not NULL, the |
|
|
|
function will set the pointed variable to X, otherwise it will ignore it. |
|
|
|
Do we want to remove that from the API? That will be difficult to map in different languages. |
|
|
|
So, in the document we seem to really rely on the possibility of pointers being NULL. Type definitions might be a little |
|
|
|
messiers in languages where that is not allowed by default. Rust is probably one of those. |
|
|
|
I do not really know Rust but know ML and Haskell. To present the problem, this is what they do: |
|
|
|
I can use ML as an example. |
|
|
|
For every type “T” there exists a type “T option”. |
|
|
|
There is no NULL in the language, and no implicit initial value for variables: it is mandated by the syntax that |
|
|
|
variables are initialised. |
|
|
|
So, how do we represent “absent” values? |
|
|
|
“T option” has two kind of values: “Nothing” or “Some V” where V is a value of type T. |
|
|
|
So, we rely on pointers being used both for indirection and for optionality. |
|
|
|
The point is: given a struct definition, we usually want its non-primitively-typed field to be optional. |
|
|
|
That is certainly the case for identities and messages. |
|
|
|
AGREED In theory we should accept that a lot of that work is done “by hand” by the person who writes the adapter, |
|
|
|
because the native type definition is supposed to follow the language culture |
|
|
|
|
|
|
|
## Binary |
|
|
|
|
|
|
|
I do not think that “binary” can be mapped to “char*”. We need a size as well. |
|
|
|
And I would make the char explicitly unsigned. |
|
|
|
I do not think that “binary” can be mapped to “char*”. We need a size as well. |
|
|
|
And I would make the char explicitly unsigned. |
|
|
|
|
|
|
|
## Terminology: Allocation |
|
|
|
|
|
|
|
Instead of “Primitive types are always statically allocated” I would say “objects of primitive types do not require heap |
|
|
|
allocation”. |
|
|
|
Well, I would not speak about static allocation |
|
|
|
In a bizarre implementation where such object do not live in registers, they will live on the stack. |
|
|
|
Maybe on a 16-bit machine, for example |
|
|
|
Yes. I would say “not heap-allocated”. |
|
|
|
Even if it were allocated dynamically it would be an “easy” way of allocating and destroying: completely LIFO |
|
|
|
We are speaking of “automatic variables”. Does the C speak speaks of “automatic storage”? |
|
|
|
So, the Standard speaks of “automatic storage duration” and “temporary lifetime”. |
|
|
|
I think that for primitive types we want “automatic storage duration” (always) and “temporary lifetime” (usually) |
|
|
|
|
|
|
|
About allocators, in a high-level API I would personally be happier if it were *not* possible to allocate empty objects, |
|
|
|
but only minimal already valid objects. For example an identity with all fields NULL is effectively useless. Shall every |
|
|
|
object type have an allocator? Notice that strings do not really have that. |
|
|
|
Instead of “Primitive types are always statically allocated” I would say “objects of primitive types do not require heap |
|
|
|
allocation”. |
|
|
|
Well, I would not speak about static allocation |
|
|
|
In a bizarre implementation where such object do not live in registers, they will live on the stack. |
|
|
|
Maybe on a 16-bit machine, for example |
|
|
|
Yes. I would say “not heap-allocated”. |
|
|
|
Even if it were allocated dynamically it would be an “easy” way of allocating and destroying: completely LIFO |
|
|
|
We are speaking of “automatic variables”. Does the C speak speaks of “automatic storage”? |
|
|
|
So, the Standard speaks of “automatic storage duration” and “temporary lifetime”. |
|
|
|
I think that for primitive types we want “automatic storage duration” (always) and “temporary lifetime” (usually) |
|
|
|
|
|
|
|
About allocators, in a high-level API I would personally be happier if it were *not* possible to allocate empty objects, |
|
|
|
but only minimal already valid objects. For example an identity with all fields NULL is effectively useless. Shall every |
|
|
|
object type have an allocator? Notice that strings do not really have that. |
|
|
|
|
|
|
|
## Ambiguity of T |
|
|
|
|
|
|
|
In the document “*T” (different from “T*”) refers to a C type, not expressible in the IDL language, which is the |
|
|
|
translation of T into C dereferenced once. Nice: “*T” is used consistently in the document. But I would define it |
|
|
|
explicitly. |
|
|
|
Maybe we can be more precise about T and “the translation of T into the language” without being too verbose |
|
|
|
theoreticians like to use “fat brackets” for this |
|
|
|
Here they are: 〚 〛 |
|
|
|
So, we could say T and 〚T〛 |
|
|
|
In the document “*T” (different from “T*”) refers to a C type, not expressible in the IDL language, which is the |
|
|
|
translation of T into C dereferenced once. Nice: “*T” is used consistently in the document. But I would define it |
|
|
|
explicitly. |
|
|
|
Maybe we can be more precise about T and “the translation of T into the language” without being too verbose |
|
|
|
theoreticians like to use “fat brackets” for this |
|
|
|
Here they are: 〚 〛 |
|
|
|
So, we could say T and 〚T〛 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|