www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - struct's fields are all public? no access control?

reply mw <mingwu gmail.com> writes:
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.
Apr 02
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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".
Apr 02
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Apr 02
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
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
Apr 02
next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
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
Apr 02
prev sibling parent reply Kagamin <spam here.lot> writes:
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.
Apr 02
parent reply Arafel <er.krali gmail.com> writes:
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
Apr 03
parent Kagamin <spam here.lot> writes:

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 

Apr 03
prev sibling parent Q. Schroll <qs.il.paperinik gmail.com> writes:
On Friday, 2 April 2021 at 15:35:03 UTC, mw wrote:
 https://run.dlang.io/is/xent7k

 ```D
 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](https://wiki.dlang.org/Access_specifiers_and_visibility#Current_sta e_of_affairs_in_D). 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](https://dlang.org/spec/attribute.html#visibility_attributes).
 **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.
Apr 05