const debacle

Walter Bright newshound1 at digitalmars.com
Sun Mar 23 11:41:14 PDT 2008


Steven Schveighoffer wrote:
> "Walter Bright" wrote
>> Steven Schveighoffer wrote:
>>> I want to specify that the function does not change the input buffer, and 
>>> returns the same type as passed in (without duping the input).
>> Look at it another way. You want to declare a filter that does not change 
>> the input, but can pass it along to another function that will. I suspect 
>> this might be a fundamentally broken concept:
>>
>>    T[] f(const T[]);
>>    void g(T[]);
>>
>>    ...
>>
>>    T[] t;
>>    g(f(t));
>>
>> What's happened here? Although f() promised it wouldn't modify t, it got 
>> modified anyway, because f() passed t to g() which modified it. Far from 
>> being a weakness in D's const regime, I think the fact that such cannot be 
>> implemented without casting away const at some point shows that the const 
>> system is sound, and trying to implement such a filter is unsound.
> 
> I wholeheartedly disagree :)
> 
> g(f(t)) is a shortcut for:
> 
> auto tmp = f(t);
> g(tmp);
> 
> and as you can see, using g on the output of f is not f's fault.

Yes, it is, because f returned a mutable reference to const data. This 
is *fundamentally* unsound because f promised not to change its input, 
and yet by returning a mutable reference to it it allows others to 
change it.

> Even if 
> you wanted a filter function, I would expect the filter to return exactly 
> the same type as it was given (as it is meant to be injected in place as an 
> argument to another function which would normally take the same input).

Splitting g(f()) into two statements with a temporary does not 
fundamentally alter anything, and if it did, that should be a huge red 
flag that something is wrong.

> Actually, your example demonstrates this point exactly.  If the code looks 
> like:
> 
> g(t);
> 
> and I say "oh, I want to filter that input with f":
> 
> g(f(t));
> 
> If f now returns const T[], then this will not compile,

right

> and the filter is 
> useless, but here comes the worst problem.  If someone else is responsible 
> for f, they might say "hey, f doesn't modify the input, so I can re-label it 
> const.  Oops, it won't let me return a mutable array, I'll just change that" 
> without realizing the implications it has on its usage.

That's right - that's what const-correctness is all about. 
Const-correctness is useless otherwise <g>.


> I think people are going to have to leave out const for such fucntions and 
> templatize them, even if they are correctly const, and therefore, const 
> loses some of its value (not to mention, if you templatize f, it can 
> generate 2 or 3 identical functions for no good reason).

Templatizing is the language solution. I know about the bloat problem, 
but that is really an implementation issue. I know the linker doesn't do 
it now, but identical blocks of generated code with different names 
should be merged.



More information about the Digitalmars-d mailing list