Why do private member variables behaved like protected in the same module when creating deriving class?

Steven Schveighoffer schveiguy at gmail.com
Thu Nov 1 18:15:43 UTC 2018


On 11/1/18 10:28 AM, Atila Neves wrote:
> On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo wrote:
>> On Tuesday, 30 October 2018 at 00:01:18 UTC, unprotected-entity wrote:
>>> On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo wrote:
>>>>
>>>> I hear you and understand you, but personally I still prefer the D 
>>>> spec as it is in this regard, except for the confusing aspect that 
>>>> you shouldn’t `alias this` a private member; but that is rather a 
>>>> limitation of alias, not of encapsulation.
>>>>
>>>
>>> If your were sitting on a plane that was running the following D 
>>> code, you might think differently ;-)
>>>
>>> --------
>>> class Plane
>>> {
>>>     private static int MAX_SPEED = 1000;
>>>
>>>     public void change_max_speed(int speed)
>>>     {
>>>         if(speed >= 1000)
>>>             MAX_SPEED = speed;
>>>     }
>>>
>>> }
>>>
>>> immutable Plane p = new Plane();
>>>
>>> // god no! why aren't you using the public interface of the class for 
>>> this!
>>> void SetMaxSpeed() { p.MAX_SPEED = -1; }
>>>
>>> void Bar() { SetMaxSpeed(); } // mmm...trouble is about to begin...
>>>
>>> void main()
>>> {
>>>     import std.stdio;
>>>
>>>     Bar(); // oohps. thanks D module. we're all going to die!
>>>
>>>     // by the time you see this, it's too late for you, and your 
>>> passengers.
>>>     writeln(p.MAX_SPEED);
>>>
>>> };
>>>
>>>
>>> -------
>>
>> :-) Why is MAX_SPEED mutable or even a runtime value, let alone signed?
> 
> Strictly my opinion below, but I believe wholeheartedly in this:
> 
> Using unsigned integers for anything except bit patterns and talking to 
> hardware is an open invitation to bugs. The C++ community has recognised 
> this and admitted that using size_t everywhere in the STL was a mistake.
> 
> "Ah, but I want type safety!". Uh-huh:
> 
> -----------------
> int[] ints;
> // indexing uses size_t, but...
> auto i = ints[-1];  // look ma, no errors or warnings!
> -----------------

It should throw an error, but actually, negative indexing is allowed in 
D or C, just on pointers only. And thanks to 2s complement math, it 
actually does index the right value.

Not saying this is preferable or good, just that it works, and does 
exactly what it should do, and what you expect it to do.

Where one generally gets into trouble is not specifying a negative 
number where an unsigned one is expected, but when one is comparing 
signed and unsigned numbers. The implicit casting definitely can make 
things more confusing than necessary. It's why I generally will avoid 
negative numbers in comparisons as much as possible. I.e. instead of 
if(x - 5 > y), I'll do if(x > y + 5).

> The problem in D and C++ is that they inherit behaviour from C, and in 
> this case the important part of that inheritance is that integers of 
> different types convert implicitly to each other. There is *no* 
> type-safety when using unsigned integers. And because bit-patterns and 
> actual integers share the same type now, people will invariably do 
> something "they're not supposed to" and perform arithmetic with these 
> values and usually wrap around. It's not pretty and it's not fun to debug.

I can see both sides. For instance Swift strictly forbids using signed 
to unsigned implicit casts, and the result is quite verbose. I write 
lots of code to find I have to add in lots of `bitPattern` and 
`truncatingBitPattern` etc. for things that are trivially obviously correct.

I find you develop a kind of numbness to it, where you reflexively add 
in your conversions without thinking about the consequences -- and you 
end up in the same place with worse-looking code.

-Steve


More information about the Digitalmars-d mailing list