Thread overview
struct's fields are all public? no access control?
Apr 02, 2021
mw
Apr 02, 2021
Adam D. Ruppe
Apr 02, 2021
12345swordy
Apr 02, 2021
12345swordy
Apr 02, 2021
Kagamin
Apr 03, 2021
Arafel
Apr 04, 2021
Kagamin
Apr 05, 2021
Q. Schroll
April 02, 2021

https://run.dlang.io/is/xent7k


import std;

struct Lady {
private int age;
int height;
float ageXHeight;
}

void main()
{
Lady p;
p.age = 20; // why can access private field here?
writeln(p.age); // why can access private field here?
}

Is this a compiler bug, or by language design?

I'd argue it should honor programmer's intention: to protect some data fields from outside access, they are intended to be kept as internal state of the struct.

April 02, 2021

On Friday, 2 April 2021 at 15:35:03 UTC, mw wrote:

>

Is this a compiler bug, or by language design?

https://dlang.org/spec/attribute.html#visibility_attributes

"Symbols with private visibility can only be accessed from within the same module. Private member functions are implicitly final and cannot be overridden."

Key word there being "module".

April 02, 2021
On 4/2/21 11:42 AM, Adam D. Ruppe wrote:
> On Friday, 2 April 2021 at 15:35:03 UTC, mw wrote:
>> Is this a compiler bug, or by language design?
> 
> https://dlang.org/spec/attribute.html#visibility_attributes
> 
> "Symbols with private visibility can only be accessed from within the same module. Private member functions are implicitly final and cannot be overridden."
> 
> 
> Key word there being "module".

To exapand on this, this is D's answer to "friend" functions in C++.

-Steve
April 02, 2021
On Friday, 2 April 2021 at 15:56:43 UTC, Steven Schveighoffer wrote:
> On 4/2/21 11:42 AM, Adam D. Ruppe wrote:
>> On Friday, 2 April 2021 at 15:35:03 UTC, mw wrote:
>>> Is this a compiler bug, or by language design?
>> 
>> https://dlang.org/spec/attribute.html#visibility_attributes
>> 
>> "Symbols with private visibility can only be accessed from within the same module. Private member functions are implicitly final and cannot be overridden."
>> 
>> 
>> Key word there being "module".
>
> To exapand on this, this is D's answer to "friend" functions in C++.
>
> -Steve

We could introduce "this private", via DIP, but there isn't much motivation behind it as the workaround is define the struct in one module and define the function in another function. The private behave differently from other languages does not seemed to effect many people here.

-Alex
April 02, 2021
On Friday, 2 April 2021 at 18:33:35 UTC, 12345swordy wrote:
> On Friday, 2 April 2021 at 15:56:43 UTC, Steven Schveighoffer wrote:
>> On 4/2/21 11:42 AM, Adam D. Ruppe wrote:
>>> On Friday, 2 April 2021 at 15:35:03 UTC, mw wrote:
>>>> Is this a compiler bug, or by language design?
>>> 
>>> https://dlang.org/spec/attribute.html#visibility_attributes
>>> 
>>> "Symbols with private visibility can only be accessed from within the same module. Private member functions are implicitly final and cannot be overridden."
>>> 
>>> 
>>> Key word there being "module".
>>
>> To exapand on this, this is D's answer to "friend" functions in C++.
>>
>> -Steve
>
> We could introduce "this private", via DIP, but there isn't much motivation behind it as the workaround is define the struct in one module and define the function in another function. The private behave differently from other languages does not seemed to effect many people here.
>
> -Alex

I meant "in another module."

-Alex
April 02, 2021
On Friday, 2 April 2021 at 18:33:35 UTC, 12345swordy wrote:
> The private behave differently from other languages does not seemed to effect many people here.

AFAIK, it copies java.
April 03, 2021
On 2/4/21 23:41, Kagamin wrote:
> On Friday, 2 April 2021 at 18:33:35 UTC, 12345swordy wrote:
>> The private behave differently from other languages does not seemed to effect many people here.
> 
> AFAIK, it copies java.

Actually no. In java, according to the spec, the encapsulation unit is the "top-level" class. The java spec says[1]:

> Otherwise, the member or constructor is declared private. Access is permitted only when the access occurs from within the body of the top level class or interface that encloses the declaration of the member or constructor.

Usually this is translated into once class per file (module, in D), because you can only have one *public* top-level class per file, (module, in D), and there aren't any free functions, so the question just doesn't usually arise.

However, although not really recommended and seldom used, you can actually have multiple classes per file, as long as only one of them is public (the rest needn't be "private", can be "package"). In this case encapsulation works between classes. This is actually quite inconsistent and can lead to weird behavior like this:

```java
public class A {
    static private class InnerA {
        private int a = 0;
    }
    static private class InnerB {
        void foo(InnerA a) {
            // InnerA can access InnerB private members
            a.a = 1;
        }
    }

    void foo(B b) {
        // But A can't acces B private members
        b.b = 1; // A.java:14: error: b has private access in B
    }
}

class B {
    private int b = 0;
}
```

So all in all, D's behavior is at least consistent and something one can get easily used to.

[1]: https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-6.6.1
April 04, 2021
On the other hand C# implements strict access control. I once needed to give access to an otherwise private member of inner class to outer class and had to declare it internal, which is a bit too broad access level, but there's no other way to solve this task in C# due to that strict access control.
April 05, 2021

On Friday, 2 April 2021 at 15:35:03 UTC, mw wrote:

>

https://run.dlang.io/is/xent7k

import std;

struct Lady {
    private int age;
    int height;
    float ageXHeight;
}

void main()
{
    Lady p;
    p.age = 20;      // why can access private field here?
    writeln(p.age);  // why can access private field here?
}

Is this a compiler bug, or by language design?

Have a look at Access specifiers and visibility. It has an error in the sense that package can be extended to super-packages. If you want to limit access, put your struct in a sub-module and place "friend" (in the C++ sense) functions in that sub-module. Then public import the sub-module in your original module. Now, private struct members are private in your sense. If you had package members, you might need the elaborate package Visibility Attribute.

>

From the spec
package may have an optional parameter in the form of a dot-separated identifier list which is resolved as the qualified package name. The package must be either the module's parent package or one of its anscestors. If this optional parameter is present, the symbol will be visible in the specified package and all of its descendants.

For example package(mw.pack) makes the affected member(s) visible to mw.pack and all its sub-modules.

Unfortunately for unit testing and quick tests, D does not allow defining multiple modules in one file.