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