digitalmars.D - in/inout/out for arrays needs clear defining
- Stewart Gordon (57/57) Jul 06 2004 Using DMD 0.94, Windows 98SE.
- Norbert Nemec (15/88) Jul 06 2004 What you say is very true: we have a problem there that needs to be solv...
Using DMD 0.94, Windows 98SE. I've long noticed a potential cause for confusion. The passing of arrays as (address, length) tuples, while sensible on the whole, leads to counter-intuitive behaviour. While it's logical to this form, it isn't what one might expect, and the spec doesn't clearly define the semantics of in/inout/out on arrays. In short: if an array is passed as in, someone might think that the contents of the array are in, when in reality only the (address, length) tuple is in; the actual array contents are inout. Of course, it's probably too late to clean up the semantics without breaking plenty of existing code. But I suppose the main point is that the semantics we have need to be clearly explained. Still, a possible idea for the future would be to allow the contents and dimensions to have separate in/inout/out settings. The idea I came up with a while back is a notation like void qwert(inout int[in] yuiop); meaning that the length is in, and the contents are inout. There would be six possibilities: in int[in] "Give me an array to look at" Pass in (address, length); either disallow changes to data in the function body, or copy on entry if any changes can occur inout int[in] "Give me the size and some starting data, and I'll play around with the data" Pass in (address, length); allow the contents to be modified in-place (current treatment of in int[], except that changing the length should be disallowed) out int[in] "Give me the size, and I'll give you the data" Pass in (address, length); initialise the array elements on entry; allow the contents to be modified in-place inout int[inout] "Give me an array, and I'll do what I like with it" Pass in reference to (address, length); anything goes (current treatment of inout int[]) out int[inout] "Give me a starting size, and I'll give you the data, changing the size if I want" Pass in reference to (address, length); initialise the array elements on entry; anything goes out int[out] "I'll give you an array" Pass in reference to (address, length), which is initialised to null Of course, the other combinations in[inout], in[out], inout[out] make little or no sense. I guess the extension to arrays of arrays would be straightforward, but I'm not sure. And combined with the existing system, while the syntax of my idea doesn't clash with it, it would cause confusion. And it would probalby clash if we tried to extend it to static array parameters. Maybe there's a better notation.... Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 06 2004
What you say is very true: we have a problem there that needs to be solved. Anyhow, I fear, documenting the current behavior is all we can do: Regulating what the routine is allowed to do with the referenced data would be equal to going for const references, which you should not even mention if you want to live in peace with Walter.... In any case, one should be aware that the behavior of static arrays is defined even less. In some cases they have plain value semantics, in others they mimic the behavior of dynamic arrays being handled by reference. My preference would be to make a clear cut here and say: static arrays have value semantics throughout, dynamic arrays have reference semantics (unless you are using the magic of array/vector expressions, but that's a different topic) There is some fundamental asymmetry between the two kinds of arrays anyway, so why not make it complete instead of trying to cover it up? Stewart Gordon wrote:Using DMD 0.94, Windows 98SE. I've long noticed a potential cause for confusion. The passing of arrays as (address, length) tuples, while sensible on the whole, leads to counter-intuitive behaviour. While it's logical to this form, it isn't what one might expect, and the spec doesn't clearly define the semantics of in/inout/out on arrays. In short: if an array is passed as in, someone might think that the contents of the array are in, when in reality only the (address, length) tuple is in; the actual array contents are inout. Of course, it's probably too late to clean up the semantics without breaking plenty of existing code. But I suppose the main point is that the semantics we have need to be clearly explained. Still, a possible idea for the future would be to allow the contents and dimensions to have separate in/inout/out settings. The idea I came up with a while back is a notation like void qwert(inout int[in] yuiop); meaning that the length is in, and the contents are inout. There would be six possibilities: in int[in] "Give me an array to look at" Pass in (address, length); either disallow changes to data in the function body, or copy on entry if any changes can occur inout int[in] "Give me the size and some starting data, and I'll play around with the data" Pass in (address, length); allow the contents to be modified in-place (current treatment of in int[], except that changing the length should be disallowed) out int[in] "Give me the size, and I'll give you the data" Pass in (address, length); initialise the array elements on entry; allow the contents to be modified in-place inout int[inout] "Give me an array, and I'll do what I like with it" Pass in reference to (address, length); anything goes (current treatment of inout int[]) out int[inout] "Give me a starting size, and I'll give you the data, changing the size if I want" Pass in reference to (address, length); initialise the array elements on entry; anything goes out int[out] "I'll give you an array" Pass in reference to (address, length), which is initialised to null Of course, the other combinations in[inout], in[out], inout[out] make little or no sense. I guess the extension to arrays of arrays would be straightforward, but I'm not sure. And combined with the existing system, while the syntax of my idea doesn't clash with it, it would cause confusion. And it would probalby clash if we tried to extend it to static array parameters. Maybe there's a better notation.... Stewart.
Jul 06 2004