const debacle
Davidson Corry
davidsoncorry at comcasst.net
Tue Mar 25 18:36:11 PDT 2008
Janice Caron wrote:
> On 21/03/2008, Sean Kelly <sean at invisibleduck.org> wrote:
>> Use overloaded functions. In theory, I think this should work:
>>
>> T[] func(T)( T[] buf ) { ... }
>> const T[] func(T)( const T[] buf ) { ... }
>> invariant T[] func(T)( invariant T[] buf ) { ... }
>
> I really wish there was a better way of doing it though. Essentially,
> we want a way to auto-generate all three versions of
>
> K(T)[] func(T)(K(T)[] buf ) { ... }
>
If you will permit a newcomer to comment... ( Hi, folks. I'm new to D
but have been lurking here on and off for a few months. I've used C++
for many years...)
It seems to me that you are conflating "the type (including const-ness)
by which the function will internally refer to its inputs" with "the
type that the function can return". Those will often be the same and
usually related, but they don't have to be identical.
Put another way, the function signature makes one of two promises:
(1) you pass me X, you know it's const, I know it's const, and I cannot
in good conscience return a reference to it or any subcomponent of it
that is NOT const.
(2) you pass me X, it may or may not be const, I don't really care, all
I guarantee you is that *I* will treat it as const, but I'm not going to
impose that restriction on you when I hand it back.
Those are DIFFERENT promises, but I think both might be useful. So we
need different ways to express them. Inspired by C++
void foo(A) const;
as the way to say "function foo() won't touch your A object", I suggest
idem(x) foo(const T x, const U y); // first promise
idem(y) bar(T x const, U y const); // second promise
The first signature RIGOROUSLY protects the constness of the data
referred to by x (or any reference derived from it). Even if you pass it
a non-const T that gets automatically cast to const, it will not return
a non-const reference to the underlying data.
The second signature, in contrast, DOESN'T make that same guarantee. It
doesn't cast the data referenced to the first parameter to const. The
compiler gets a hint that the function is SUPPOSED TO treat the
underlying data as const, and may throw warnings or errors if it sees
the function doing things that wouldn't be const-safe (including calls
to other functions that don't make the necessary guarantees in THEIR
signatures...). But bar() is not constrained to return a reference to
const data.
[note: idem(y) means "the same type and const-ness as parameter y".
(Latin "the same"). I regret that I'm a bit confused about auto(y)
and whether it would work here. If it would do so unambiguously,
excellent and certainly don't introduce an unnecessary keyword.]
[and substitute "invariant" above wherever you see "const" and do the
same analysis.]
[I also can't yet see a clean syntax to do the TransferConst! thing...]
Does this make any sense? Or have I said something silly, or resurrected
an old and discarded idea, or otherwise taken a pratfall on my maiden sally?
Hi, all! Nice to meet you!
-- Davidson Corry
More information about the Digitalmars-d
mailing list