Array as an argument, ambiguous behaviour.
Steven Schveighoffer
schveiguy at yahoo.com
Thu Jan 30 11:50:41 PST 2014
On Thu, 30 Jan 2014 13:58:55 -0500, Cooler <kulkin at hotbox.ru> wrote:
>>>>> The D principle - "The program compile and runs as expected, or not
>>>>> compile at all".
>>>>
>>>> This is a fantasy. The compiler cannot know what you expect.
>>> The language is needed to express your intentions to the compiler.
>>
>> Anything that the compiler cannot enforce is just documentation. Does
>> it matter whether the documentation is in a comment or part of the
>> signature?
> Why we need "const" keyword, while we can just put "I promise do not
> change it" in the documentation?
const is only useful in cases where references are involved. In this case,
you want to make the *copied* data constant, in hopes that you then can't
accidentally stop referencing the original.
In another example, there is little to be gained from a signature such as:
void foo(const int x);
What does this say about foo? Nothing. I can pass in a mutable, const, or
immutable int, because a copy is made. It doesn't provide any more
guarantees to the caller than:
void foo(int x);
Likewise, your proposed "int[] const" would not guarantee anything extra
to the caller beyond "int[]", because both are copies put onto the stack.
The function has no access to the original values.
Arrays in D are hard to understand. They don't behave like arrays in most
other languages. But they foster a different mindset I think, that results
in some of the fastest code on the planet. But one has to understand the
semantics of syntax if they want to properly use the language. For
functions which append/extend and then write data to the prior piece (the
only non-deterministic case), special care has to be taken to explain this
to the caller. I would think a mechanism to attempt detecting this and
flagging it would be a worthy lint tool feature. But not a language or
compiler feature. There is just simply no way to say "that is always bad"
or that you know what the intentions of the author are.
The other case you specified, when the author re-assigns a slice and
expects it to be a memcpy or to re-bind the calling parameter, the result
is deterministically the wrong result, and the coder will notice it right
away (and hopefully correct their understanding). I don't think we need a
language feature for that, just documentation (which I think we have).
Let me also suggest you use scope statements to verify at runtime that the
case you intend to prevent doesn't actually happen:
void foo(int[] x)
{
const origx = x;
scope(exit) assert(origx.ptr == x.ptr);
...
}
While not perfect, and not static, it should at least avoid subtle bugs
(and can be turned off in release mode).
-Steve
More information about the Digitalmars-d-learn
mailing list