{技术}{C++}{讨论}设想:将unix文件系统用户/权限管理思路引入C++

已查看 8 次
跳至第一个未读帖子

张慧聪

未读,
2009年8月3日 22:48:352009/8/3
收件人 pongba
不知你是否遇到过这种情况,在一个类里,做了个方法,只是希望在某个特定的地方调用,其他的地方均不希望发生这个调用,传统是使用3pf(public/private/protected/friend)的手段来实现。我今天早上突然想到如题的思路,用以替换传统的3pf模型。具体描述如下:

在同一命名空间里,每声明一个类或(不属于任何类的)函数,则添加相应的同名用户和组。例如,如果我们声明了
class A; class B; class C;void f(int);
则现在有四个用户:A,B,C,f
和四个组:A,B,C,f
对于一个类来说,每个类的成员(数据成员和函数成员)为这个类所own。
一个继承类将属于父类所在的组。

如何实现访问控制呢?
类的每成员都有一个权限flag,比如,对于class A
{
private:
  int a;
public:
  A(int a_){a = a_;}
  void show(void){cout << a << endl;}
};
那么有
a drw-------
A cr-xr-xr-x
show mr-xr-xr-x
d(data)表示a是一个数据成员。我们将后面的flag用|分成三段rw-|r--|---:rw-表示owner可读写;这意味着A的方法可以对其进行读写,接下来的---表示用组用户不可读写,也即子类不可读写;同样,后面的---表示其他用户不可读写。
类似的,对于A(),c表示constructor,这种标识表示大家都可以访问,执行
对于show(),m代表method,其他同A()
对于数据成员,每一段flag里不可以出现x
对于static,简单地将w变成-就行了

我们可以用关键字flag来取代传统的3pf例如下面代码:
group A:B, echo_a;
class A
{
flag 644:
  int a;
flag 050:
  int tell_a_to_groupers(void){return a;}
flag c---r-xr-x:
  A(int a_){a = a_;}
  int tell_a_to_others(void){return a;}
};
class B
{
flag 550:
  void show_a_add_5(A anA){cout << anA.tell_a_to_groupers() + 5 << endl;}
}
void echo_a(A anA)
{
  cout << anA.tell_a_to_groupers() << endl;
}
void other(A anA)
{
  cout << anA.tell_a_to_others() << endl;
}
flag后面可以直接跟码,也可以跟字符串。对于上面的050,表示我们不希望类自己的方法调用该方法(以前试过在虚构函数里调用构造函数,g++没报错,一运行就成了死循环,当然,可能没人会这么做:-p)

我们可以规定一个class中的默认flag,比如c055/d640/m555,如果我们不声明任何标记的话就使用默认值
我们可以通过关键字umask来改变类里默认的flag

这里我们注意,一个flag段只能有四种值:0,4,5,6,其他的值都是非法的,没人希望一个函数是“可写”的,也没人希望一个数据可以“执行”,一个不可r(意味着可见)但可x的函数也是奇怪的。

为了兼容旧代码,3pf的手段可以保留,编译的时候只需要将其翻译为相应的flag就好。

说说好处
首先,程序复杂一些的时候,这个需求和文件系统中权限控制的需求几乎一模一样,所以这种引入非常自然,而且从概念上讲也要清晰很多;
第二,访问控制可以做得更加精细和清晰,使用umask会带来更多方便;
第三,提供了新的控制功能:
1)我们注意4这个flag值,它是非常有用的,因为它意味着只读,这应该是现有的3pf无法提供的。一但我们用了static,那就永远static了,谁也不能动,如果不static,那么要么可以改,要么不能读。而如果我们设一个d644的flag,意味着对同组及其他可见,但只有类自己的方法才能更改其值,个人认为这很有诱惑力
2)注意050,我们可以禁止类自己的方法调用自己的某些方法,当然,这可以很容易地从编程上避免

说说坏处
增加复杂性是当然的。3pf的写法成为了一个子集,两者共存的代码,如果不严格注意而随便滥用,那代码将完全不可读。即使全部使用新手段,满天乱飞的flag数字也会把人搞得很晕。但不注意缩进的代码不也是完全不可读的么?这就需要新的编程风格守则来进行约束。如果引入权限概念,那么所有C++程序员都需要一个思维的转变,从原有的3pf中解脱出来,用用户/组+rwx的思路来理解--让人们做出这种转变怕是不易。

OK,就想了这么多,欢迎大家拍砖指教:-p

pi1ot

未读,
2009年8月3日 23:01:132009/8/3
收件人 TopLanguage
猛一看标题感觉如此常用的功能怎么我没想到呢,再仔细想想,貌似写了这么多年代码还真没这么用过这东西。
似乎更应该从接口设计上解决这个表面问题的内在原因吧,而不是偏硬性的权限方式。

On 8月4日, 上午10时48分, 张慧聪 <zhcfree...@gmail.com> wrote:
> 不知你是否遇到过这种情况,在一个类里,做了个方法,只是希望在某个特定的地方调用,其他的地方均不希望发生这个调用,传统是使用3pf(public/pri-vate/protected/friend)的手段来实现。我今天早上突然想到如题的思路,用以替换传统的3pf模型。具体描述如下:


>
> 在同一命名空间里,每声明一个类或(不属于任何类的)函数,则添加相应的同名用户和组。例如,如果我们声明了
> class A; class B; class C;void f(int);
> 则现在有四个用户:A,B,C,f
> 和四个组:A,B,C,f
> 对于一个类来说,每个类的成员(数据成员和函数成员)为这个类所own。
> 一个继承类将属于父类所在的组。
>
> 如何实现访问控制呢?
> 类的每成员都有一个权限flag,比如,对于class A
> {
> private:
> int a;
> public:
> A(int a_){a = a_;}
> void show(void){cout << a << endl;}};
>
> 那么有
> a drw-------
> A cr-xr-xr-x
> show mr-xr-xr-x

> d(data)表示a是一个数据成员。我们将后面的flag用|分成三段rw-|r--|---:rw-表示owner可读写;这意味着A的方法可以对其进行读-写,接下来的---表示用组用户不可读写,也即子类不可读写;同样,后面的---表示其他用户不可读写。


> 类似的,对于A(),c表示constructor,这种标识表示大家都可以访问,执行
> 对于show(),m代表method,其他同A()
> 对于数据成员,每一段flag里不可以出现x
> 对于static,简单地将w变成-就行了
>
> 我们可以用关键字flag来取代传统的3pf例如下面代码:
> group A:B, echo_a;
> class A
> {
> flag 644:
> int a;
> flag 050:
> int tell_a_to_groupers(void){return a;}
> flag c---r-xr-x:
> A(int a_){a = a_;}
> int tell_a_to_others(void){return a;}};
>
> class B
> {
> flag 550:
> void show_a_add_5(A anA){cout << anA.tell_a_to_groupers() + 5 << endl;}}
>
> void echo_a(A anA)
> {
> cout << anA.tell_a_to_groupers() << endl;}
>
> void other(A anA)
> {
> cout << anA.tell_a_to_others() << endl;}
>

> flag后面可以直接跟码,也可以跟字符串。对于上面的050,表示我们不希望类自己的方法调用该方法(以前试过在虚构函数里调用构造函数,g++没报错,一运-行就成了死循环,当然,可能没人会这么做:-p)
>
> 我们可以规定一个class中的默认flag,比如c055/d640/m555,如果我们不声明任何标记的话就使用默认值
> 我们可以通过关键字umask来改变类里默认的flag
>
> 这里我们注意,一个flag段只能有四种值:0,4,5,6,其他的值都是非法的,没人希望一个函数是"可写"的,也没人希望一个数据可以"执行",一个不可r-(意味着可见)但可x的函数也是奇怪的。


>
> 为了兼容旧代码,3pf的手段可以保留,编译的时候只需要将其翻译为相应的flag就好。
>
> 说说好处
> 首先,程序复杂一些的时候,这个需求和文件系统中权限控制的需求几乎一模一样,所以这种引入非常自然,而且从概念上讲也要清晰很多;
> 第二,访问控制可以做得更加精细和清晰,使用umask会带来更多方便;
> 第三,提供了新的控制功能:

> 1)我们注意4这个flag值,它是非常有用的,因为它意味着只读,这应该是现有的3pf无法提供的。一但我们用了static,那就永远static了,谁也-不能动,如果不static,那么要么可以改,要么不能读。而如果我们设一个d644的flag,意味着对同组及其他可见,但只有类自己的方法才能更改其值,个-人认为这很有诱惑力


> 2)注意050,我们可以禁止类自己的方法调用自己的某些方法,当然,这可以很容易地从编程上避免
>
> 说说坏处

> 增加复杂性是当然的。3pf的写法成为了一个子集,两者共存的代码,如果不严格注意而随便滥用,那代码将完全不可读。即使全部使用新手段,满天乱飞的flag数-字也会把人搞得很晕。但不注意缩进的代码不也是完全不可读的么?这就需要新的编程风格守则来进行约束。如果引入权限概念,那么所有C++程序员都需要一个思维的-转变,从原有的3pf中解脱出来,用用户/组+rwx的思路来理解--让人们做出这种转变怕是不易。
>
> OK,就想了这么多,欢迎大家拍砖指教:-p

qiaojie

未读,
2009年8月4日 00:05:442009/8/4
收件人 pon...@googlegroups.com
我基本上连class都懒得写了,对外用struct定义纯虚接口,在内部实现的类里面也直接用struct。忘记无聊的public/private/protected吧

2009/8/4 张慧聪 <zhcfr...@gmail.com>

up duan

未读,
2009年8月4日 00:06:372009/8/4
收件人 pon...@googlegroups.com
是个好想法。
不过UNIX的权限管理粒度太粗了,基于ACL的才能实施完全的控制。所以,可以看看Eiffel里面的相关信息,比楼主想的好。

OwnWaterloo

未读,
2009年8月3日 23:52:182009/8/3
收件人 TopLanguage
>没人希望一个函数是"可写"的,也没人希望一个数据可以"执行",一个不可r (意味着可见)但可x的函数也是奇怪的。
这可不一定

On 8月4日, 上午10时48分, 张慧聪 <zhcfree...@gmail.com> wrote:

> 不知你是否遇到过这种情况,在一个类里,做了个方法,只是希望在某个特定的地方调用,其他的地方均不希望发生这个调用,传统是使用3pf(public/pri vate/protected/friend)的手段来实现。我今天早上突然想到如题的思路,用以替换传统的3pf模型。具体描述如下:


>
> 在同一命名空间里,每声明一个类或(不属于任何类的)函数,则添加相应的同名用户和组。例如,如果我们声明了
> class A; class B; class C;void f(int);
> 则现在有四个用户:A,B,C,f
> 和四个组:A,B,C,f
> 对于一个类来说,每个类的成员(数据成员和函数成员)为这个类所own。
> 一个继承类将属于父类所在的组。
>
> 如何实现访问控制呢?
> 类的每成员都有一个权限flag,比如,对于class A
> {
> private:
> int a;
> public:
> A(int a_){a = a_;}
> void show(void){cout << a << endl;}};
>
> 那么有
> a drw-------
> A cr-xr-xr-x
> show mr-xr-xr-x

> d(data)表示a是一个数据成员。我们将后面的flag用|分成三段rw-|r--|---:rw-表示owner可读写;这意味着A的方法可以对其进行读 写,接下来的---表示用组用户不可读写,也即子类不可读写;同样,后面的---表示其他用户不可读写。


> 类似的,对于A(),c表示constructor,这种标识表示大家都可以访问,执行
> 对于show(),m代表method,其他同A()
> 对于数据成员,每一段flag里不可以出现x
> 对于static,简单地将w变成-就行了
>
> 我们可以用关键字flag来取代传统的3pf例如下面代码:
> group A:B, echo_a;
> class A
> {
> flag 644:
> int a;
> flag 050:
> int tell_a_to_groupers(void){return a;}
> flag c---r-xr-x:
> A(int a_){a = a_;}
> int tell_a_to_others(void){return a;}};
>
> class B
> {
> flag 550:
> void show_a_add_5(A anA){cout << anA.tell_a_to_groupers() + 5 << endl;}}
>
> void echo_a(A anA)
> {
> cout << anA.tell_a_to_groupers() << endl;}
>
> void other(A anA)
> {
> cout << anA.tell_a_to_others() << endl;}
>

> flag后面可以直接跟码,也可以跟字符串。对于上面的050,表示我们不希望类自己的方法调用该方法(以前试过在虚构函数里调用构造函数,g++没报错,一运 行就成了死循环,当然,可能没人会这么做:-p)
>
> 我们可以规定一个class中的默认flag,比如c055/d640/m555,如果我们不声明任何标记的话就使用默认值
> 我们可以通过关键字umask来改变类里默认的flag
>
> 这里我们注意,一个flag段只能有四种值:0,4,5,6,其他的值都是非法的,没人希望一个函数是"可写"的,也没人希望一个数据可以"执行",一个不可r (意味着可见)但可x的函数也是奇怪的。


>
> 为了兼容旧代码,3pf的手段可以保留,编译的时候只需要将其翻译为相应的flag就好。
>
> 说说好处
> 首先,程序复杂一些的时候,这个需求和文件系统中权限控制的需求几乎一模一样,所以这种引入非常自然,而且从概念上讲也要清晰很多;
> 第二,访问控制可以做得更加精细和清晰,使用umask会带来更多方便;
> 第三,提供了新的控制功能:

> 1)我们注意4这个flag值,它是非常有用的,因为它意味着只读,这应该是现有的3pf无法提供的。一但我们用了static,那就永远static了,谁也 不能动,如果不static,那么要么可以改,要么不能读。而如果我们设一个d644的flag,意味着对同组及其他可见,但只有类自己的方法才能更改其值,个 人认为这很有诱惑力


> 2)注意050,我们可以禁止类自己的方法调用自己的某些方法,当然,这可以很容易地从编程上避免
>
> 说说坏处

> 增加复杂性是当然的。3pf的写法成为了一个子集,两者共存的代码,如果不严格注意而随便滥用,那代码将完全不可读。即使全部使用新手段,满天乱飞的flag数 字也会把人搞得很晕。但不注意缩进的代码不也是完全不可读的么?这就需要新的编程风格守则来进行约束。如果引入权限概念,那么所有C++程序员都需要一个思维的 转变,从原有的3pf中解脱出来,用用户/组+rwx的思路来理解--让人们做出这种转变怕是不易。
>
> OK,就想了这么多,欢迎大家拍砖指教:-p

久远

未读,
2009年8月4日 02:17:002009/8/4
收件人 TopLanguage
没有什么必要吧,public/protected/private+继承 可以构造出足够灵活的访问控制规则,因为基类中定义的函数的访问控制可以在
派生类中更改,所以可以给不同的用户编写不同的派生类控制访问。

然后关于楼主提出的新方法,我有两个疑问;
一个是,编写代码的时候是否需要预知可能出现的用户组的类型,就是说,编写代码的时候就能确定,只有ABCD这四个用户组可能会访问到这些代码,然后强
制所有需要访问这些代码的用户都属于或者继承于这些已经已经预知的用户组?
另一个是,多重继承的情况下,派生类的权限怎样计算,是使用交集还是并集还是使用新的flag进行控制?这种情况下会不会带来潜在的危险行为?

总体上感觉楼主给的方法的确要更灵活,但是考虑到代码可读性以及编译器亲和性之类的问题的话,可能不一定比现有的方式更合算。

张慧聪

未读,
2009年8月4日 09:40:322009/8/4
收件人 pon...@googlegroups.com
2009/8/4 pi1ot <pilot.cn@gmail.com>
猛一看标题感觉如此常用的功能怎么我没想到呢,再仔细想想,貌似写了这么多年代码还真没这么用过这东西。
似乎更应该从接口设计上解决这个表面问题的内在原因吧,而不是偏硬性的权限方式。
和C++里使用private这种硬性的东西出现的目的一样,新的设想是为了让这种手段更好用。接口设计的问题当然更重要,但这种说法和"我们不需要C++,用C写更好的程序"是一个思路,虽然我的说法有点极端:-p

张慧聪

未读,
2009年8月4日 09:41:412009/8/4
收件人 pon...@googlegroups.com
2009/8/4 qiaojie <qia...@gmail.com>
我基本上连class都懒得写了,对外用struct定义纯虚接口,在内部实现的类里面也直接用struct。忘记无聊的public/private/protected吧
难道3pf本来就是没用的?

张慧聪

未读,
2009年8月4日 09:43:022009/8/4
收件人 pon...@googlegroups.com
2009/8/4 up duan <fix...@gmail.com>

是个好想法。
不过UNIX的权限管理粒度太粗了,基于ACL的才能实施完全的控制。所以,可以看看Eiffel里面的相关信息,比楼主想的好。
还粗呀?在程序设计语言里已经足够了吧?难道得像svn一样搞个权限配置文件吗?:-p

张慧聪

未读,
2009年8月4日 09:43:512009/8/4
收件人 pon...@googlegroups.com
2009/8/4 OwnWaterloo <ownwa...@gmail.com>

>没人希望一个函数是"可写"的,也没人希望一个数据可以"执行",一个不可r (意味着可见)但可x的函数也是奇怪的。
这可不一定
想了半天没想出可能出现的情况,应该极少吧?能不能举个例子?

Shuo Chen

未读,
2009年8月4日 09:44:572009/8/4
收件人 TopLanguage
一个程序里全部public也没什么不好,防贼似地防着别人调用,有必要吗?

一句
#define private public
就解除武装了。

张慧聪

未读,
2009年8月4日 09:51:422009/8/4
收件人 pon...@googlegroups.com
2009/8/4 久远 <d3dc...@gmail.com>

没有什么必要吧,public/protected/private+继承 可以构造出足够灵活的访问控制规则,因为基类中定义的函数的访问控制可以在
派生类中更改,所以可以给不同的用户编写不同的派生类控制访问。
但是这个从概念上更自然呀,而且能实现原文中提到的新功能,比如只读,觉得还是挺有意义的。

然后关于楼主提出的新方法,我有两个疑问;
一个是,编写代码的时候是否需要预知可能出现的用户组的类型,就是说,编写代码的时候就能确定,只有ABCD这四个用户组可能会访问到这些代码,然后强
制所有需要访问这些代码的用户都属于或者继承于这些已经已经预知的用户组?
这个我忘记说了,其实也有提到,那就是使用group语句来新建一个组,大概是下面样子:
group aGroup: user1, user2, user3
其中user是已经有的user,我觉得没有必要搞新的user出来,但把相关的user放在一个组里是很有用的。

另一个是,多重继承的情况下,派生类的权限怎样计算,是使用交集还是并集还是使用新的flag进行控制?这种情况下会不会带来潜在的危险行为?
如果class A继承于class A1和class A2那么,A就同时属于group A1和group A2,权限的设定在于程序员,感觉没什么危险的吧:)

总体上感觉楼主给的方法的确要更灵活,但是考虑到代码可读性以及编译器亲和性之类的问题的话,可能不一定比现有的方式更合算。
是啊,所以才发上来讨论,觉得蛮有意义的:-)

张慧聪

未读,
2009年8月4日 09:57:142009/8/4
收件人 pon...@googlegroups.com
2009/8/4 Shuo Chen <gian...@gmail.com>

一个程序里全部public也没什么不好,防贼似地防着别人调用,有必要吗?

一句
#define private public
就解除武装了。
呵呵,是啊,不过这样思路能更清晰啊

lvscar

未读,
2009年8月4日 10:23:512009/8/4
收件人 TopLanguage
粗看了一下:
no.1 代码级权限控制是不信任程序员的表现, 务实点引入命名规范就好。 以技术的手段不信任技术人员往往适得其反
no.2 引入user,group会增加耦合度
no.3. 函数可以被decorate,数据能被eval
no.4 发这个不利于找工作

On Aug 4, 10:48 am, 张慧聪 <zhcfree...@gmail.com> wrote:

居振梁

未读,
2009年8月4日 10:32:432009/8/4
收件人 pon...@googlegroups.com
如果要这样的话,不妨参考下ActionScript 3的namespace机制,这个ns并不是package,就相当于你这里的group。
当然as3的灵活性没你的强,而且一个成员和方法只能属于一个ns,3p是特殊的ns。

2009/8/4 张慧聪 <zhcfr...@gmail.com>

这个我忘记说了,其实也有提到,那就是使用group语句来新建一个组,大概是下面样子:
group aGroup: user1, user2, user3
其中user是已经有的user,我觉得没有必要搞新的user出来,但把相关的user放在一个组里是很有用的。



--
良师益友 黑客精神 清心寡欲
http://wargrey.yo2.cn
http://wargrey.blogspot.com
主要兴趣:Unix/GNU Linux、人工智能、虚拟化、心理学、数学
其他兴趣:自然科学、武术、自然语言、魔幻

raymond

未读,
2009年8月4日 10:50:562009/8/4
收件人 TopLanguage
这种方法和3PS基本并列,只是3PS我们已经用了很长时间,我们现在的需求使用3ps都可以解决,同样,使用楼主提供的方法也肯定能解决,这种方法似
乎没有明显的优势,想法倒是非常有趣的

On 8月4日, 下午10时32分, 居振梁 <juzhenli...@gmail.com> wrote:
> 如果要这样的话,不妨参考下ActionScript 3的namespace机制,这个ns并不是package,就相当于你这里的group。
> 当然as3的灵活性没你的强,而且一个成员和方法只能属于一个ns,3p是特殊的ns。
>

> 2009/8/4 张慧聪 <zhcfree...@gmail.com>


>
> > 这个我忘记说了,其实也有提到,那就是使用group语句来新建一个组,大概是下面样子:
> > group aGroup: user1, user2, user3
> > 其中user是已经有的user,我觉得没有必要搞新的user出来,但把相关的user放在一个组里是很有用的。
>
> --

> 良师益友 黑客精神 清心寡欲http://wargrey.yo2.cnhttp://wargrey.blogspot.com

pi1ot

未读,
2009年8月4日 11:17:572009/8/4
收件人 TopLanguage
对4.比较感兴趣,展开说说

On 8月4日, 下午10时23分, lvscar <lvs...@gmail.com> wrote:
> 粗看了一下:
> no.1 代码级权限控制是不信任程序员的表现, 务实点引入命名规范就好。 以技术的手段不信任技术人员往往适得其反
> no.2 引入user,group会增加耦合度
> no.3. 函数可以被decorate,数据能被eval
> no.4 发这个不利于找工作
>
> On Aug 4, 10:48 am, 张慧聪 <zhcfree...@gmail.com> wrote:
>
>
>

> > 不知你是否遇到过这种情况,在一个类里,做了个方法,只是希望在某个特定的地方调用,其他的地方均不希望发生这个调用,传统是使用3pf(public/pri-vate/protected/friend)的手段来实现。我今天早上突然想到如题的思路,用以替换传统的3pf模型。具体描述如下:


>
> > 在同一命名空间里,每声明一个类或(不属于任何类的)函数,则添加相应的同名用户和组。例如,如果我们声明了
> > class A; class B; class C;void f(int);
> > 则现在有四个用户:A,B,C,f
> > 和四个组:A,B,C,f
> > 对于一个类来说,每个类的成员(数据成员和函数成员)为这个类所own。
> > 一个继承类将属于父类所在的组。
>
> > 如何实现访问控制呢?
> > 类的每成员都有一个权限flag,比如,对于class A
> > {
> > private:
> > int a;
> > public:
> > A(int a_){a = a_;}
> > void show(void){cout << a << endl;}};
>
> > 那么有
> > a drw-------
> > A cr-xr-xr-x
> > show mr-xr-xr-x

> > d(data)表示a是一个数据成员。我们将后面的flag用|分成三段rw-|r--|---:rw-表示owner可读写;这意味着A的方法可以对其进行读-写,接下来的---表示用组用户不可读写,也即子类不可读写;同样,后面的---表示其他用户不可读写。


> > 类似的,对于A(),c表示constructor,这种标识表示大家都可以访问,执行
> > 对于show(),m代表method,其他同A()
> > 对于数据成员,每一段flag里不可以出现x
> > 对于static,简单地将w变成-就行了
>
> > 我们可以用关键字flag来取代传统的3pf例如下面代码:
> > group A:B, echo_a;
> > class A
> > {
> > flag 644:
> > int a;
> > flag 050:
> > int tell_a_to_groupers(void){return a;}
> > flag c---r-xr-x:
> > A(int a_){a = a_;}
> > int tell_a_to_others(void){return a;}};
>
> > class B
> > {
> > flag 550:
> > void show_a_add_5(A anA){cout << anA.tell_a_to_groupers() + 5 << endl;}}
>
> > void echo_a(A anA)
> > {
> > cout << anA.tell_a_to_groupers() << endl;}
>
> > void other(A anA)
> > {
> > cout << anA.tell_a_to_others() << endl;}
>

> > flag后面可以直接跟码,也可以跟字符串。对于上面的050,表示我们不希望类自己的方法调用该方法(以前试过在虚构函数里调用构造函数,g++没报错,一运-行就成了死循环,当然,可能没人会这么做:-p)
>
> > 我们可以规定一个class中的默认flag,比如c055/d640/m555,如果我们不声明任何标记的话就使用默认值
> > 我们可以通过关键字umask来改变类里默认的flag
>
> > 这里我们注意,一个flag段只能有四种值:0,4,5,6,其他的值都是非法的,没人希望一个函数是"可写"的,也没人希望一个数据可以"执行",一个不可r-(意味着可见)但可x的函数也是奇怪的。


>
> > 为了兼容旧代码,3pf的手段可以保留,编译的时候只需要将其翻译为相应的flag就好。
>
> > 说说好处
> > 首先,程序复杂一些的时候,这个需求和文件系统中权限控制的需求几乎一模一样,所以这种引入非常自然,而且从概念上讲也要清晰很多;
> > 第二,访问控制可以做得更加精细和清晰,使用umask会带来更多方便;
> > 第三,提供了新的控制功能:

> > 1)我们注意4这个flag值,它是非常有用的,因为它意味着只读,这应该是现有的3pf无法提供的。一但我们用了static,那就永远static了,谁也-不能动,如果不static,那么要么可以改,要么不能读。而如果我们设一个d644的flag,意味着对同组及其他可见,但只有类自己的方法才能更改其值,个-人认为这很有诱惑力


> > 2)注意050,我们可以禁止类自己的方法调用自己的某些方法,当然,这可以很容易地从编程上避免
>
> > 说说坏处

> > 增加复杂性是当然的。3pf的写法成为了一个子集,两者共存的代码,如果不严格注意而随便滥用,那代码将完全不可读。即使全部使用新手段,满天乱飞的flag数-字也会把人搞得很晕。但不注意缩进的代码不也是完全不可读的么?这就需要新的编程风格守则来进行约束。如果引入权限概念,那么所有C++程序员都需要一个思维的-转变,从原有的3pf中解脱出来,用用户/组+rwx的思路来理解--让人们做出这种转变怕是不易。
>
> > OK,就想了这么多,欢迎大家拍砖指教:-p- 隐藏被引用文字 -
>
> - 显示引用的文字 -

居振梁

未读,
2009年8月4日 11:21:322009/8/4
收件人 pon...@googlegroups.com
我也感兴趣
顺便把多余的引文去掉。

2009/8/4 pi1ot <pilot.cn@gmail.com>
对4.比较感兴趣,展开说说

On 8月4日, 下午10时23分, lvscar <lvs...@gmail.com> wrote:
> no.4  发这个不利于找工作



--
良师益友 黑客精神 清心寡欲
http://wargrey.yo2.cn

lvscar

未读,
2009年8月4日 11:48:182009/8/4
收件人 TopLanguage

On Aug 4, 11:17 pm, pi1ot <pilot...@gmail.com> wrote:
> 对4.比较感兴趣,展开说说
这idea在现有平台下创造不出价值
想法太玄不便于操控

张慧聪

未读,
2009年8月4日 12:09:282009/8/4
收件人 pon...@googlegroups.com
2009/8/4 居振梁 <juzhe...@gmail.com>

我也感兴趣
顺便把多余的引文去掉。

2009/8/4 pi1ot <pilot.cn@gmail.com>
对4.比较感兴趣,展开说说

On 8月4日, 下午10时23分, lvscar <lvs...@gmail.com> wrote:
> no.4  发这个不利于找工作
啊,俺还在找工作,或者说,再过一阵准备找工作,PS一个,lvscar是俺哥们儿,呵呵

Jia

未读,
2009年8月4日 05:22:322009/8/4
收件人 TopLanguage
个人感觉要达到 "只是希望在某个特定的地方调用,其他的地方均不希望发生这个调用" 这个目的不用这么麻烦,通常的 PImpl 方式就能达到要求
//a.h
class a_impl;
class a
{
public:
a();
void m1();
protected:
a_impl * m_p;
};
//a.cpp
class a_impl
{
public:
void p_m1() {}
void p_m2() {}
};

a::a()
{
m_p = new a_impl();
}

void a::m1()
{
m_p->p_m1();
m_p->p_m1();
}

其中 m1 是一定要暴露的方法,p_m1 p_m2 是实现 m1 但不希望外边知道的方法

On Aug 4, 10:48 am, 张慧聪 <zhcfree...@gmail.com> wrote:

Cheng, Long

未读,
2009年8月4日 11:44:572009/8/4
收件人 pon...@googlegroups.com
现代的高级语言里面自修改代码的情况已经不多了。不过对于第二种情况,可以
“执行”的数据倒是很常见。我们项目里面就有类似的代码,运行时生成代码执行。
另外一个常见的情况就是jit compiler的虚拟机。这种代码在开了强制DEP的系统
上会被干掉。我们前段时间就碰到这样的bug,在windows server 2008的系统上默
认是强制全开DEP的,一跑程序就直接挂掉了。还好当时一看挂掉的栈马上想到这
个情况了。
分享一下这个经验,如果有同学碰到类似的情况马上查查系统DEP的状态。

张慧聪 写道:
> 2009/8/4 OwnWaterloo <ownwa...@gmail.com
> <mailto:ownwa...@gmail.com>>

张慧聪

未读,
2009年8月4日 13:29:002009/8/4
收件人 pon...@googlegroups.com


2009/8/4 Jia <lij...@gmail.com>
个人感觉要达到 "只是希望在某个特定的地方调用,其他的地方均不希望发生这个调用" 这个目的不用这么麻烦,通常的 PImpl 方式就能达到要求
//a.cpp
class a_impl
{
public:
 void p_m1() {}
 void p_m2() {}
};

其中 m1 是一定要暴露的方法,p_m1 p_m2 是实现 m1 但不希望外边知道的方法
对啊,但是它们是可以被调用的啊,如果你是希望pm1 pm2都只能被a来用的话,那就达不到目的了。

OwnWaterloo

未读,
2009年8月4日 13:57:202009/8/4
收件人 TopLanguage
> 想了半天没想出可能出现的情况,应该极少吧?能不能举个例子?

数据执行的例子:
static const unsigned char code[] = {
0x0x,0x31, /* rdtsc */
0xc3, /* ret */
};
static uint64_t (* const timestamp)(void) = (uint64_t (*)(void))code;

uint32_t t1 = timestamp(),t2;
/* work */
t2 = timestamp();

——目的
某些编译器不支持内嵌汇编(或者不知其语法),或者内嵌汇编不支持ReaD TimeStamp Counter这一指令。
为了在这种编译器上用C语言使用该指令,可以这样做。

“写函数”的例子:
在《beautiful code》有一章(好像是“动态生成代码”)中提到一种方法,实现bitblt。


r是Read,x是eXecute?
不可r但x的例子…… 严格的说, 执行之前一定会读。
但有些操作系统或者处理器是区分“用于执行的读”,和普通读的。
win32上内存权限就有PAGE_EXECUTE, 可执行但不可读写。


例子举完了。


其实如果编译器能提供这些功能, 当然,最好是有个标准, 并能获得广泛支持(如果只是一两个编译器的扩展,为了这点功能影响可移植性就不太值得
了)。

就像C++对多重继承的支持, 不需要的人可以当它不存在。
如果一旦需要, 没有该支持就很麻烦。

如果真能做到:
x: // 给编译器提示:下面的数据可执行, 那是很爽的事情。
static cont char executable_code[];

否者要绕不小的弯子。


btw:
lz可以少花一些力气在这(指TL)上面,毕竟要“说服别人(即使自己正确)”是很费劲且几乎不可能的事。
想想多重继承纳入C++标准受到了多少阻力(甚至现在都被人诟病)。

可以在这里搜集完善一些想法,再将设想(甚至一部分实现方案)报告给C++标准委员会。 不过我觉得通过的可能性不高……
不必和所有人较真。

居振梁

未读,
2009年8月4日 20:27:432009/8/4
收件人 pon...@googlegroups.com
如果有时间,并且不急于摆脱现状,可以把这想法作为自己开发的系统的宏语言来试试。
基础研究不需要一开始就有价值,只需验证一下,这样做是否可行,如果确实必要再说。

我也是“无业游民”

2009/8/4 lvscar <lvs...@gmail.com>
这idea在现有平台下创造不出价值
想法太玄不便于操控

久远

未读,
2009年8月4日 21:16:112009/8/4
收件人 TopLanguage
On 8月5日, 上午8时27分, 居振梁 <juzhenli...@gmail.com> wrote:
> 如果有时间,并且不急于摆脱现状,可以把这想法作为自己开发的系统的宏语言来试试。
> 基础研究不需要一开始就有价值,只需验证一下,这样做是否可行,如果确实必要再说。

赞同,的确可以现在某个简单的语言里面试验一下。

up duan

未读,
2009年8月4日 21:27:002009/8/4
收件人 pon...@googlegroups.com


2009/8/4 张慧聪 <zhcfr...@gmail.com>
是还粗。作为UNIX文件系统的权限管理,大可认为已经够了,但是作为通用目的语言的机制,显然还不够啊。因为你没有办法预测你的权限机制将要被用于什么场合。

不需要权限配置文件,Eiffel中的『客户 』就已经足够描述ACL了。

张慧聪

未读,
2009年8月5日 08:49:392009/8/5
收件人 pon...@googlegroups.com
2009/8/4 OwnWaterloo <ownwa...@gmail.com>
> 想了半天没想出可能出现的情况,应该极少吧?能不能举个例子?

数据执行的例子:
为了在这种编译器上用C语言使用该指令,可以这样做。
原来是这样,长见识了,谢谢:-)

“写函数”的例子:
在《beautiful code》有一章(好像是“动态生成代码”)中提到一种方法,实现bitblt。
回头去查一下
r是Read,x是eXecute?
是的
不可r但x的例子……    严格的说, 执行之前一定会读。
但有些操作系统或者处理器是区分“用于执行的读”,和普通读的。
win32上内存权限就有PAGE_EXECUTE, 可执行但不可读写。

其实如果编译器能提供这些功能, 当然,最好是有个标准, 并能获得广泛支持(如果只是一两个编译器的扩展,为了这点功能影响可移植性就不太值得
了)。
是啊,觉得是挺极端的情况,有点奇技淫巧的感觉了。

就像C++对多重继承的支持, 不需要的人可以当它不存在。
如果一旦需要, 没有该支持就很麻烦。
是啊,不需要的地方可以不用啊。

如果真能做到:
x: // 给编译器提示:下面的数据可执行, 那是很爽的事情。
static cont char executable_code[];

否者要绕不小的弯子。


btw:
lz可以少花一些力气在这(指TL)上面,毕竟要“说服别人(即使自己正确)”是很费劲且几乎不可能的事。
想想多重继承纳入C++标准受到了多少阻力(甚至现在都被人诟病)。

可以在这里搜集完善一些想法,再将设想(甚至一部分实现方案)报告给C++标准委员会。 不过我觉得通过的可能性不高……
不必和所有人较真。
有道理!!

张慧聪

未读,
2009年8月5日 08:51:322009/8/5
收件人 pon...@googlegroups.com
2009/8/5 居振梁 <juzhe...@gmail.com>

如果有时间,并且不急于摆脱现状,可以把这想法作为自己开发的系统的宏语言来试试。
基础研究不需要一开始就有价值,只需验证一下,这样做是否可行,如果确实必要再说。
呃,好建议,这需要很强的功力才行

我也是“无业游民”
呵呵,这个我们可以私下聊聊?也算是熟人了,我gtalk长年在线

张慧聪

未读,
2009年8月5日 08:52:022009/8/5
收件人 pon...@googlegroups.com
2009/8/5 久远 <d3dc...@gmail.com>
有这样的简单语言么?推荐一个?

居振梁

未读,
2009年8月5日 09:22:452009/8/5
收件人 pon...@googlegroups.com
他这意思就是指自己写一个
据说“写编译器是unix程序员的基本功”啊!

2009/8/5 张慧聪 <zhcfr...@gmail.com>

--
良师益友 黑客精神 清心寡欲
http://wargrey.yo2.cn
http://wargrey.blogspot.com
主要兴趣:Unix/GNU Linux、人工智能、虚拟化、心理学、数学
其他兴趣:自然科学、武术、自然语言、人文文化、科幻魔幻

张慧聪

未读,
2009年8月5日 09:33:472009/8/5
收件人 pon...@googlegroups.com
2009/8/5 居振梁 <juzhe...@gmail.com>
他这意思就是指自己写一个
据说“写编译器是unix程序员的基本功”啊!
惭愧啊,回头就去试试!

pi1ot

未读,
2009年8月5日 10:34:372009/8/5
收件人 TopLanguage
编译器?简单解释器还好,编译器有点溢出

On 8月5日, 下午9时22分, 居振梁 <juzhenli...@gmail.com> wrote:
> 他这意思就是指自己写一个
> 据说“写编译器是unix程序员的基本功”啊!
>

> 2009/8/5 张慧聪 <zhcfree...@gmail.com>
>
> > 2009/8/5 久远 <d3dco...@gmail.com>


>
> > On 8月5日, 上午8时27分, 居振梁 <juzhenli...@gmail.com> wrote:
> >> > 如果有时间,并且不急于摆脱现状,可以把这想法作为自己开发的系统的宏语言来试试。
> >> > 基础研究不需要一开始就有价值,只需验证一下,这样做是否可行,如果确实必要再说。
>
> >> 赞同,的确可以现在某个简单的语言里面试验一下。
>
> > 有这样的简单语言么?推荐一个?
>
> --

> 良师益友 黑客精神 清心寡欲http://wargrey.yo2.cnhttp://wargrey.blogspot.com

居振梁

未读,
2009年8月5日 10:41:152009/8/5
收件人 pon...@googlegroups.com
恩,应该是解释器

2009/8/5 pi1ot <pilot.cn@gmail.com>
编译器?简单解释器还好,编译器有点溢出



--
良师益友 黑客精神 清心寡欲
http://wargrey.yo2.cn

马涛

未读,
2009年8月7日 00:21:382009/8/7
收件人 pon...@googlegroups.com
没有必要,访问控制这个东西不知道有什么必要。如果你不应该访问它,那么你就不访问就好。
2009/8/4 OwnWaterloo <ownwa...@gmail.com>
>没人希望一个函数是"可写"的,也没人希望一个数据可以"执行",一个不可r (意味着可见)但可x的函数也是奇怪的。
这可不一定

On 8月4日, 上午10时48分, 张慧聪 <zhcfree...@gmail.com> wrote:
> 不知你是否遇到过这种情况,在一个类里,做了个方法,只是希望在某个特定的地方调用,其他的地方均不希望发生这个调用,传统是使用3pf(public/pri vate/protected/friend)的手段来实现。我今天早上突然想到如题的思路,用以替换传统的3pf模型。具体描述如下:

>
> 在同一命名空间里,每声明一个类或(不属于任何类的)函数,则添加相应的同名用户和组。例如,如果我们声明了
> class A; class B; class C;void f(int);
> 则现在有四个用户:A,B,C,f
> 和四个组:A,B,C,f
> 对于一个类来说,每个类的成员(数据成员和函数成员)为这个类所own。
> 一个继承类将属于父类所在的组。
>
> 如何实现访问控制呢?
> 类的每成员都有一个权限flag,比如,对于class A
> {
> private:
>   int a;
> public:
>   A(int a_){a = a_;}
>   void show(void){cout << a << endl;}};
>
> 那么有
> a drw-------
> A cr-xr-xr-x
> show mr-xr-xr-x
> d(data)表示a是一个数据成员。我们将后面的flag用|分成三段rw-|r--|---:rw-表示owner可读写;这意味着A的方法可以对其进行读 写,接下来的---表示用组用户不可读写,也即子类不可读写;同样,后面的---表示其他用户不可读写。

> 类似的,对于A(),c表示constructor,这种标识表示大家都可以访问,执行
> 对于show(),m代表method,其他同A()
> 对于数据成员,每一段flag里不可以出现x
> 对于static,简单地将w变成-就行了
>
> 我们可以用关键字flag来取代传统的3pf例如下面代码:
> group A:B, echo_a;
> class A
> {
> flag 644:
>   int a;
> flag 050:
>   int tell_a_to_groupers(void){return a;}
> flag c---r-xr-x:
>   A(int a_){a = a_;}
>   int tell_a_to_others(void){return a;}};
>
> class B
> {
> flag 550:
>   void show_a_add_5(A anA){cout << anA.tell_a_to_groupers() + 5 << endl;}}
>
> void echo_a(A anA)
> {
>   cout << anA.tell_a_to_groupers() << endl;}
>
> void other(A anA)
> {
>   cout << anA.tell_a_to_others() << endl;}
>
> flag后面可以直接跟码,也可以跟字符串。对于上面的050,表示我们不希望类自己的方法调用该方法(以前试过在虚构函数里调用构造函数,g++没报错,一运 行就成了死循环,当然,可能没人会这么做:-p)
>
> 我们可以规定一个class中的默认flag,比如c055/d640/m555,如果我们不声明任何标记的话就使用默认值
> 我们可以通过关键字umask来改变类里默认的flag
>
> 这里我们注意,一个flag段只能有四种值:0,4,5,6,其他的值都是非法的,没人希望一个函数是"可写"的,也没人希望一个数据可以"执行",一个不可r (意味着可见)但可x的函数也是奇怪的。

>
> 为了兼容旧代码,3pf的手段可以保留,编译的时候只需要将其翻译为相应的flag就好。
>
> 说说好处
> 首先,程序复杂一些的时候,这个需求和文件系统中权限控制的需求几乎一模一样,所以这种引入非常自然,而且从概念上讲也要清晰很多;
> 第二,访问控制可以做得更加精细和清晰,使用umask会带来更多方便;
> 第三,提供了新的控制功能:
> 1)我们注意4这个flag值,它是非常有用的,因为它意味着只读,这应该是现有的3pf无法提供的。一但我们用了static,那就永远static了,谁也 不能动,如果不static,那么要么可以改,要么不能读。而如果我们设一个d644的flag,意味着对同组及其他可见,但只有类自己的方法才能更改其值,个 人认为这很有诱惑力

> 2)注意050,我们可以禁止类自己的方法调用自己的某些方法,当然,这可以很容易地从编程上避免
>
> 说说坏处
> 增加复杂性是当然的。3pf的写法成为了一个子集,两者共存的代码,如果不严格注意而随便滥用,那代码将完全不可读。即使全部使用新手段,满天乱飞的flag数 字也会把人搞得很晕。但不注意缩进的代码不也是完全不可读的么?这就需要新的编程风格守则来进行约束。如果引入权限概念,那么所有C++程序员都需要一个思维的 转变,从原有的3pf中解脱出来,用用户/组+rwx的思路来理解--让人们做出这种转变怕是不易。
>
> OK,就想了这么多,欢迎大家拍砖指教:-p

机械唯物主义

未读,
2009年8月8日 08:17:372009/8/8
收件人 TopLanguage
专案开发中,应该会有约定,什么样的方法可以调用,什么样的方法可以被调用。
这个应该是开发过程的问题,检查的方法。。可以通过代码审查或者写个工具来查,加到代码中不合适,可能会引入bug.

On Aug 7, 12:21 pm, 马涛 <qing...@gmail.com> wrote:
> 没有必要,访问控制这个东西不知道有什么必要。如果你不应该访问它,那么你就不访问就好。

> 2009/8/4 OwnWaterloo <ownwater...@gmail.com>

回复全部
回复作者
转发
0 个新帖子