www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Lack of privacy?

reply "Kris" <fu bar.com> writes:
module SomeStruct;

static Foo S;

private
{
   struct Foo {int x;}
}

===================

in some other file:

===================

import SomeStruct;

void main(char[][] args)
{
    Foo foo;  // should this be visible?
} 
Nov 12 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Sat, 12 Nov 2005 18:37:47 -0800, Kris wrote:

 module SomeStruct;
 
 static Foo S;
 
 private
 {
    struct Foo {int x;}
 }
 
 ===================
 
 in some other file:
 
 ===================
 
 import SomeStruct;
 
 void main(char[][] args)
 {
     Foo foo;  // should this be visible?
 }

Yes. The "private" attribute only works on members and not on the containers. You cannot have private classes or private structs. But you can have classes and structs with private methods and private data. module SomeStruct; static Foo S; struct Foo {private int x;} =================== =================== import SomeStruct; void main(char[][] args) { Foo foo; // this is still visible. foo.x = 1; // this fails: member x is not accessible } -- Derek Parnell Melbourne, Australia 13/11/2005 5:33:48 PM
Nov 12 2005
parent reply kris <fu bar.org> writes:
Thx ~ but is that how it /should/ operate?

Seems rather counter-intuitive and, if the 'containers' are always 
forced to be public, then it should surely be an error to tag them as 
anything but?


Derek Parnell wrote:
 On Sat, 12 Nov 2005 18:37:47 -0800, Kris wrote:
 
 
module SomeStruct;

static Foo S;

private
{
   struct Foo {int x;}
}

===================

in some other file:

===================

import SomeStruct;

void main(char[][] args)
{
    Foo foo;  // should this be visible?
}

Yes. The "private" attribute only works on members and not on the containers. You cannot have private classes or private structs. But you can have classes and structs with private methods and private data. module SomeStruct; static Foo S; struct Foo {private int x;} =================== =================== import SomeStruct; void main(char[][] args) { Foo foo; // this is still visible. foo.x = 1; // this fails: member x is not accessible }

Nov 13 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sun, 13 Nov 2005 00:44:54 -0800, kris <fu bar.org> wrote:
 Thx ~ but is that how it /should/ operate?

 Seems rather counter-intuitive and, if the 'containers' are always  
 forced to be public, then it should surely be an error to tag them as  
 anything but?

Something needs to be done, however there are several questions and/or key concepts to consider... 1. instance vs declaration. A class declaration cannot currently be private, but a class instance can. eg. private class A {} //declaration, not private private A a = new A(); //instance, private Is this right or wrong? Should there be a difference between these? 2. http://www.digitalmars.com/d/attribute.html "Private module members are equivalent to static declarations in C programs." In fact private is not the same as "static" in C. "private" prevents access to an instance outside the module it exists in. C "static" prevents visibility, the symbol actually "does not exist" outside the file. Do we need a keyword/feature that actually does what C "static" does? The general feeling I get is that people want to make class declarations private to prevent pollution of the namespace, however, private doesn't actually achieve that, the symbol is still 'exported' from the file, all private would do is prevent the use of it. (maybe that's all people want?) Take this example from a day or two ago: D/29368 The private function actually collides with a public one, this is due to private not hiding the symbol, just preventing access. So, do people actually want "static" from C? as opposed to "private" in D? The problem with "static" from C is the error messages it generates, they're typically "symbol cannot be found" type errors, which makes sense, the compiler has actually 'forgotten' about the symbol because it "doesn't exist" outside the file it's in. Ideally the compiler should know about the symbol but give a more helpful message like "class A is private to module foo.bar", to do that it cannot implement "static" from C, but has to do it more like "private" in D currently is. This post is intended as food for thought, as opposed to an "answer" or a solid opinion. Regan
Nov 13 2005
next sibling parent reply "John C" <johnch_atms hotmail.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message 
news:opsz58j5e123k2f5 nrage.netwin.co.nz...
 On Sun, 13 Nov 2005 00:44:54 -0800, kris <fu bar.org> wrote:
 Thx ~ but is that how it /should/ operate?

 Seems rather counter-intuitive and, if the 'containers' are always 
 forced to be public, then it should surely be an error to tag them as 
 anything but?

Something needs to be done, however there are several questions and/or key concepts to consider... 1. instance vs declaration. A class declaration cannot currently be private, but a class instance can. eg. private class A {} //declaration, not private private A a = new A(); //instance, private Is this right or wrong? Should there be a difference between these? 2. http://www.digitalmars.com/d/attribute.html "Private module members are equivalent to static declarations in C programs." In fact private is not the same as "static" in C. "private" prevents access to an instance outside the module it exists in. C "static" prevents visibility, the symbol actually "does not exist" outside the file. Do we need a keyword/feature that actually does what C "static" does? The general feeling I get is that people want to make class declarations private to prevent pollution of the namespace, however, private doesn't actually achieve that, the symbol is still 'exported' from the file, all private would do is prevent the use of it. (maybe that's all people want?) Take this example from a day or two ago: D/29368 The private function actually collides with a public one, this is due to private not hiding the symbol, just preventing access. So, do people actually want "static" from C? as opposed to "private" in D? The problem with "static" from C is the error messages it generates, they're typically "symbol cannot be found" type errors, which makes sense, the compiler has actually 'forgotten' about the symbol because it "doesn't exist" outside the file it's in. Ideally the compiler should know about the symbol but give a more helpful message like "class A is private to module foo.bar", to do that it cannot implement "static" from C, but has to do it more like "private" in D currently is. This post is intended as food for thought, as opposed to an "answer" or a solid opinion. Regan

Is it that complicated? I'd have thought tagging anything as "private" should hide it from anything outside its parent scope. So a private class should only be accessed and seen within its enclosing class or, if it's at module level, enclosing module. The same would apply for private functions. Private should also be the default when no protection is specified (not public, as it is now). To allow other modules access to and visibility of internal classes, "package" should be used. I can't think of a reason why you'd want external modules to even see, let alone access, private data structures. This sounds to me like a simple, reliable method. That the language has not sorted out this issue by now is a little hard to believe.
Nov 13 2005
parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
John C wrote:
 Is it that complicated? I'd have thought tagging anything as "private" 
 should hide it from anything outside its parent scope. So a private class 
 should only be accessed and seen within its enclosing class or, if it's at 
 module level, enclosing module. The same would apply for private functions.

Yes, this is the way Java acts (AFAIK). I've tried to find out, why the D implementation seems to be currently broken. Walter has been quite quiet about this.
 
 Private should also be the default when no protection is specified (not 
 public, as it is now). To allow other modules access to and visibility of 
 internal classes, "package" should be used. I can't think of a reason why 
 you'd want external modules to even see, let alone access, private data 
 structures.

Neither do I. Again, this is how Java works (AFAIK). I think it's fine, but shouldn't we use 'public' instead of 'package', when public access to the module members is wanted?
 
 This sounds to me like a simple, reliable method. That the language has not 
 sorted out this issue by now is a little hard to believe. 
 
 

polymorphism doesn't work either (at least in the way Java does it ;) ), but that's another story.
Nov 13 2005
parent "John C" <johnch_atms hotmail.com> writes:
"Jari-Matti Mäkelä" <jmjmak invalid_utu.fi> wrote in message 
news:dl8ans$249$1 digitaldaemon.com...
 John C wrote:
 Is it that complicated? I'd have thought tagging anything as "private" 
 should hide it from anything outside its parent scope. So a private class 
 should only be accessed and seen within its enclosing class or, if it's 
 at module level, enclosing module. The same would apply for private 
 functions.

Yes, this is the way Java acts (AFAIK).

And C#.
 I've tried to find out, why the D implementation seems to be currently 
 broken. Walter has been quite quiet about this.

 Private should also be the default when no protection is specified (not 
 public, as it is now). To allow other modules access to and visibility of 
 internal classes, "package" should be used. I can't think of a reason why 
 you'd want external modules to even see, let alone access, private data 
 structures.

Neither do I. Again, this is how Java works (AFAIK). I think it's fine, but shouldn't we use 'public' instead of 'package', when public access to the module members is wanted?

Yes, in most cases, especially to grant access to user code. I was talking specifically about internal structures that you don't want to expose to user code, yet do want other modules in your own library to access.
 This sounds to me like a simple, reliable method. That the language has 
 not sorted out this issue by now is a little hard to believe.

polymorphism doesn't work either (at least in the way Java does it ;) ), but that's another story.

Nov 13 2005
prev sibling parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Regan Heath wrote:
 On Sun, 13 Nov 2005 00:44:54 -0800, kris <fu bar.org> wrote:
 
 Thx ~ but is that how it /should/ operate?

 Seems rather counter-intuitive and, if the 'containers' are always  
 forced to be public, then it should surely be an error to tag them as  
 anything but?

Something needs to be done, however there are several questions and/or key concepts to consider... 1. instance vs declaration. A class declaration cannot currently be private, but a class instance can. eg. private class A {} //declaration, not private private A a = new A(); //instance, private Is this right or wrong? Should there be a difference between these? 2. http://www.digitalmars.com/d/attribute.html "Private module members are equivalent to static declarations in C programs." In fact private is not the same as "static" in C. "private" prevents access to an instance outside the module it exists in. C "static" prevents visibility, the symbol actually "does not exist" outside the file. Do we need a keyword/feature that actually does what C "static" does? The general feeling I get is that people want to make class declarations private to prevent pollution of the namespace, however, private doesn't actually achieve that, the symbol is still 'exported' from the file, all private would do is prevent the use of it. (maybe that's all people want?)

Isn't it quite clear that if two alternatives for class foo are available, we should use the non-private one and if both of them are 'public', the compiler reports an error?
 
 Take this example from a day or two ago:
 D/29368

There's also an example that reveals this is an implementation bug: http://www.digitalmars.com/d/attribute.html: "Static does not have the additional C meaning of being local to a file. Use the private attribute in D to achieve that. For example:" module foo; int x = 3; // x is global private int y = 4; // y is local to module foo Now if you try to access that 'private int y' from another module, the compiler doesn't exit with an error.
 
 The private function actually collides with a public one, this is due 
 to  private not hiding the symbol, just preventing access.

It should hide the private symbol, when another symbol with public visibility is accessible/visible.
 
 So, do people actually want "static" from C? as opposed to "private" in D?
 
 The problem with "static" from C is the error messages it generates,  
 they're typically "symbol cannot be found" type errors, which makes 
 sense,  the compiler has actually 'forgotten' about the symbol because 
 it "doesn't  exist" outside the file it's in.
 
 Ideally the compiler should know about the symbol but give a more 
 helpful  message like "class A is private to module foo.bar", to do that 
 it cannot  implement "static" from C, but has to do it more like 
 "private" in D  currently is.

I agree.
Nov 13 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sun, 13 Nov 2005 23:42:07 +0200, Jari-Matti Mäkelä  
<jmjmak invalid_utu.fi> wrote:
 Regan Heath wrote:
 On Sun, 13 Nov 2005 00:44:54 -0800, kris <fu bar.org> wrote:

 Thx ~ but is that how it /should/ operate?

 Seems rather counter-intuitive and, if the 'containers' are always   
 forced to be public, then it should surely be an error to tag them as   
 anything but?

and/or key concepts to consider... 1. instance vs declaration. A class declaration cannot currently be private, but a class instance can. eg. private class A {} //declaration, not private private A a = new A(); //instance, private Is this right or wrong? Should there be a difference between these? 2. http://www.digitalmars.com/d/attribute.html "Private module members are equivalent to static declarations in C programs." In fact private is not the same as "static" in C. "private" prevents access to an instance outside the module it exists in. C "static" prevents visibility, the symbol actually "does not exist" outside the file. Do we need a keyword/feature that actually does what C "static" does? The general feeling I get is that people want to make class declarations private to prevent pollution of the namespace, however, private doesn't actually achieve that, the symbol is still 'exported' from the file, all private would do is prevent the use of it. (maybe that's all people want?)

Isn't it quite clear that if two alternatives for class foo are available, we should use the non-private one and if both of them are 'public', the compiler reports an error?

I think you're correct, however consider the possiblity that the coder meant to use the private one but didn't realise it was private. I think it's fairly safe to assume the public one, its likely the coder will discover their mistake as soon as they call a method on the class which exists on the private one and not the public one. Further, assuming we have a well documented library the coder isn't likely to be aware of the private one, as it wont be documented as the public one would. All I was actually trying to do with this post was illustrate that private does not actually hide symbols, it just prevents access to them. That and ask the question "which do we actually want?"
  Take this example from a day or two ago:
 D/29368

There's also an example that reveals this is an implementation bug: http://www.digitalmars.com/d/attribute.html: "Static does not have the additional C meaning of being local to a file. Use the private attribute in D to achieve that. For example:" module foo; int x = 3; // x is global private int y = 4; // y is local to module foo Now if you try to access that 'private int y' from another module, the compiler doesn't exit with an error.

I believe the bug is only with symbols specified in complete form, IIRC: [a.d] import b; void main() { y = 5; //error b.y = 5; //ok } [b.d] private int y = 4; both of those should be an error.
  The private function actually collides with a public one, this is due  
 to  private not hiding the symbol, just preventing access.

It should hide the private symbol, when another symbol with public visibility is accessible/visible.

Yet, however as we agree below it cannot 'forget' about the symbol as it does in C.
  So, do people actually want "static" from C? as opposed to "private"  
 in D?
  The problem with "static" from C is the error messages it generates,   
 they're typically "symbol cannot be found" type errors, which makes  
 sense,  the compiler has actually 'forgotten' about the symbol because  
 it "doesn't  exist" outside the file it's in.
  Ideally the compiler should know about the symbol but give a more  
 helpful  message like "class A is private to module foo.bar", to do  
 that it cannot  implement "static" from C, but has to do it more like  
 "private" in D  currently is.

I agree.

Regan
Nov 13 2005
parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
Regan Heath wrote:
  The private function actually collides with a public one, this is 
 due  to  private not hiding the symbol, just preventing access.

It should hide the private symbol, when another symbol with public visibility is accessible/visible.

Yet, however as we agree below it cannot 'forget' about the symbol as it does in C.

No, of course not. We need some 'intelligent' compiler logic here. I'm not wise enough to make a working compiler, but I'm sure Walter is. I just don't want it to be default behavior to explicitly call foomodule.fooclass every time I need some 'external' classes. Perhaps it helps that D can always "loan" some functionality from C#/Java as there seems to be consensus that these languages do these things 'right'.
  So, do people actually want "static" from C? as opposed to 
 "private"  in D?
  The problem with "static" from C is the error messages it 
 generates,   they're typically "symbol cannot be found" type errors, 
 which makes  sense,  the compiler has actually 'forgotten' about the 
 symbol because  it "doesn't  exist" outside the file it's in.
  Ideally the compiler should know about the symbol but give a more  
 helpful  message like "class A is private to module foo.bar", to do  
 that it cannot  implement "static" from C, but has to do it more 
 like  "private" in D  currently is.

I agree.

Regan

Nov 13 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 14 Nov 2005 02:09:23 +0200, Jari-Matti Mäkelä  
<jmjmak invalid_utu.fi> wrote:
 Regan Heath wrote:
  The private function actually collides with a public one, this is  
 due  to  private not hiding the symbol, just preventing access.

It should hide the private symbol, when another symbol with public visibility is accessible/visible.

it does in C.

No, of course not. We need some 'intelligent' compiler logic here.

Agreed.
 I just don't want it to be default behavior to explicitly call  
 foomodule.fooclass every time I need some 'external' classes.

You can use 'alias' to aleviate some of the problem, eg. import a; import b; alias a.foo foo; foo(); //calls a.foo; Regan
Nov 13 2005