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 19:26:05 UTC 2018


On 11/1/18 2:46 PM, Patrick Schluter wrote:
> On Thursday, 1 November 2018 at 14:28:27 UTC, 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!
>> -----------------
>>
>> 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 have literally lost count of how many bugs I've had to fix due to 
>> unsigned integers. `long` is large enough for anything you need, as 
>> Java has shown for 2 decades now.
>>
>> Friends don't let friends use unsigned types for counting.
> 
> My experience is exactly the opposite. I inherited a code base of ~200K 
> lines of C written over 3 decades by several developers of varying 
> skills. You can not imagine how many bugs I found thanks to replacing 
> int and long by size_t and uint32_t/uint64_t.
> 
> int i = 0;
> ints[--i];  // look ma, no errors or warnings! indeed
> 
> with size_t i at least you get segfault or a bus error.

My testing looks like it's the same:

#include <stdio.h>
int main()
{
     int arr[5];
     int *ptr = arr + 1; // point at second element so we can do 
negative indexing legally
     int idx1 = 0;
     ptr[--idx1] = 5;
     printf("%d\n", arr[0]); // 5
     size_t idx2 = 0;
     ptr[--idx2] = 6;
     printf("%d\n", arr[0]); // 6
     return 0;
}

-Steve


More information about the Digitalmars-d mailing list