Bjarne老大说:不,不可能了

35 views
Skip to first unread message

pongba

unread,
Nov 14, 2007, 5:39:33 AM11/14/07
to pon...@googlegroups.com
以下节选自与Bjarne最近的通信:
 
> 3. Non-LR Gramma. It's hurting the IDE community really. At first it
> seems to be a innocuous problem. But I think it has everything to do
> with the fact that we, until now, still don't have a fast-and-acurate
> C++ parser. I know the reason behind it from you HOP-III paper. What
> I'm wondering is that is this going to change in the future? Will C++
> have a LR gramma of some sort?

   No. That can't be done.

呃... 大家说说吧..

也许等后来处理器速度实在快了,这个问题就消失了... 有点讽刺吧,这个话似乎在Java社区听到过..哈哈
Anyway,这个问题到底有多大,大家怎么看?

另外,我记得C++ FQA里面说,由于C++的语法是上下文敏感的,所以如果有时候你把目光猛盯着几行局部代码,在缺乏上下文的情况下你就无法解析出其含义。举的例子我忘了。哪位熟悉编译原理的解释解释?:-)

BTW. 其它通信内容暂且不表,因为还在询问一些东东,而且也没得到许可可以公布私人邮件哈:P 等问完了我概括一下意思用中文表达出来吧。
Bjarne答应给那篇《Why C++》写一个"可发布版本"的友情评点,真是个热心银啊。等收到了第一时间公布出来..
近几年C++的现状在国内有些微妙,是不是应该索性再访谈一下B老大呢?

--
刘未鹏(pongba)|C++的罗浮宫
http://blog.csdn.net/pongba
TopLanguage
http://groups.google.com/group/pongba

莫华枫

unread,
Nov 14, 2007, 6:05:26 AM11/14/07
to pon...@googlegroups.com
做个访谈不错。或许我们这里可以先收集一些问题,考考他老人家。:)

在07-11-14,pongba <pon...@gmail.com> 写道:



--
反者道之动,弱者道之用
m...@seaskysh.com
longsh...@gmail.com
http://blog.csdn.net/longshanks/

莫华枫

unread,
Nov 15, 2007, 2:36:11 AM11/15/07
to pon...@googlegroups.com
关于上下文敏感问题,我认为被夸大了。C系语法的语言(C++、Java、C#等)实际上都存在这个问题。而C#等更严重。但唯独C++背了这个黑锅。
Thing.fun();
请告诉我,Thing是什么?类还是对象?
在C#里(或者任何不区分::和.的语言里),不知道,得看Thing的声明或定义。
但在C++里,我可以明确地说,Thing肯定是对象。

在07-11-14,pongba <pon...@gmail.com> 写道:

SpitFire

unread,
Nov 15, 2007, 3:00:29 AM11/15/07
to pon...@googlegroups.com
到动态语言更不得了

比如ruby a.b 这个b你还真不知道是哪的

在07-11-15,莫华枫 <longsh...@gmail.com> 写道:



--
SpitFire

oldrev

unread,
Nov 15, 2007, 3:06:41 AM11/15/07
to pon...@googlegroups.com
Thing 是对象还是类的问题应该属于语义范围,不是语法。

pongba

unread,
Nov 15, 2007, 3:32:47 AM11/15/07
to pon...@googlegroups.com
但谁也不能否认,一个C++ Parser比C# Parser要远远难做。根本问题是什么呢?

pongba

unread,
Nov 15, 2007, 3:36:52 AM11/15/07
to pon...@googlegroups.com
但谁也不能否认,一个C++ Parser比C# Parser要远远难做。根本问题是什么呢?

On Nov 15, 2007 3:36 PM, 莫华枫 <longsh...@gmail.com> wrote:

莫华枫

unread,
Nov 15, 2007, 3:38:05 AM11/15/07
to pon...@googlegroups.com
比较C++和C#的特性清单嘛。C#砍掉的东西比留下的东西还多,而且都是些难缠的特性。
一辆自行车总比摩托车难造吧。:)

在07-11-15,pongba <pon...@gmail.com> 写道:

莫华枫

unread,
Nov 15, 2007, 3:39:23 AM11/15/07
to pon...@googlegroups.com
错了错了:
一辆摩托车总比自行车难造吧。:b

在07-11-15,莫华枫 <longsh...@gmail.com> 写道:

莫华枫

unread,
Nov 15, 2007, 7:50:17 PM11/15/07
to pon...@googlegroups.com


在07-11-15,oldrev <old...@gmail.com> 写道:
Thing 是对象还是类的问题应该属于语义范围,不是语法。

那么这个呢:
  y=x(20);
只看这一句,我们能够断定x是类还是函数吗?
这也是语义范畴呀。这是明显的上下文相关,对吧。我觉得好一些的语法应当尽可能减少对语义的依赖。
比如采用另一种形式作为对象初始化语法:
  y=x:20;
这样就可以同函数调用分开了。
同样,区分了::和.之后,则无需进入语义层面,便可以知道Thing的含义。
non context free语法的问题就在于让不同的语义采用了相同的语法构造。要做到context free就得减少这种共用。

Jian Wang

unread,
Nov 16, 2007, 7:25:10 AM11/16/07
to pon...@googlegroups.com
C++的语法太可怕了,简直就是编译器的噩梦。但是
y=x(20);
这句话从语法分析的角度来看是没有歧义的。
语法分析的结果是抽象语法树。
上面的这句语句,分析的结果是
y和x是标示符
=是运算符
()是运算符
20是数字
x是类还是对象还是函数名,还是别的什么东西并不会影响生成的语法树。
因此这是一种上下文无关的语法。

可怕的是下面的这种语法。
a * b = c;
这句话即可能是变量声明和初始化的语法,也可能是个数学表达式加等号操作符。
这2者的语法树是不同的。必须结合上下文的语义来解释。
a**b;也有同样的歧义。究竟是变量声明还是解引用后做乘法呢?

由于c++可以在类的定义里写函数的实现,这就造成的语法分析到一半要应用语义分析的结果。但是由于语法还没完成,语义分析只能开个头,两者缠在一起,互相引用。

在模板出现之前,还不算太可怕,模板出现后,就更难分析了。
a<b,c>d怎么解析?
a<b::c,d>e(f,g).h * j::k;要参照多少上下文才能解析出来?
C++在引入模板后,到了要靠增加关键字来帮助语法解析的地步。那就是typename.
从程序员的角度来看,typename关键字纯粹就是多余的。

在 07-11-16,莫华枫<longsh...@gmail.com> 写道:

red...@gmail.com

unread,
Nov 16, 2007, 7:40:03 AM11/16/07
to pon...@googlegroups.com
Jian Wang 写道:
> 可怕的是下面的这种语法。
> a * b = c;
>
我写过简单的 C++ 编译器 (不支持模板, 不支持类继承). 这里这个应该不是问题.
编译器到了可以声明, 或者可以用表达式的这个场合, 碰到 a, 首先分析, a 是
一个类型符号, 还是一个变量符号, 如果是类型符号, 那么进入声明处理代码, 如
果是变量符号, 那么进入表达式分析处理代码.

> 这句话即可能是变量声明和初始化的语法,也可能是个数学表达式加等号操作符。
> 这2者的语法树是不同的。必须结合上下文的语义来解释。
> a**b;也有同样的歧义。究竟是变量声明还是解引用后做乘法呢?
>

这个同上.

Jian Wang

unread,
Nov 16, 2007, 7:46:52 AM11/16/07
to pon...@googlegroups.com
没错,我举这个例子是为了说明什么是上下文相关的语法。
上下文相关会使得语法的解析随着语义的复杂化变得越来越复杂。
引入模板后编译时间的直线上升就很能说明问题。

在 07-11-16,red...@gmail.com<red...@gmail.com> 写道:

Googol Lee

unread,
Nov 16, 2007, 8:39:43 AM11/16/07
to TopLanguage
这个可不可以这么理解:
对于下面这个语句:
a < b > c

如果从左向右做语法解析(假设词法已经解析完毕),那么除非读到"c"字符,否则前面的"a < b >"的具体语义是不定的,到底是一个参数为b的模
板?还是一个比较语句呢?这时候编译器只得把两种状态都预存起来,只有当最终解析到字符"c"才能排除掉模板语义(因为a<b> c不合法),确认使用
比较语义,并建立合理的语法树。

那a < b > ::c,是不是除非知道a的类型,就根本没法解析了?

或者D为了避免这种情况,才把模板从<>变成了!()?

oldrev

unread,
Nov 16, 2007, 9:06:16 AM11/16/07
to pon...@googlegroups.com
我很希望能把语法统一起来,比如说专门用 ':' 处理类型,这么着typedef 也可
以取消了,直接写:
size_t : unsigned int;
模板特化也可以统一了:
template <typename T : int>
T min(const T& x, const T& y);
类继承:
class Foo : SuperFoo { ... };

还有要取消 ','表达式,顺带也取消C式强制类型转换,直接让 (x, ...) 成为
Tuple 字面值:
(int, double) record;
record[0] = 1;
record[1] = 1.1;
这下谁还需要 struct ?

世界和谐了....

oldrev

unread,
Nov 16, 2007, 9:15:24 AM11/16/07
to pon...@googlegroups.com
http://www.digitalmars.com/d/templates-revisited.html

--
"Live Long and Prosper"
- oldrev

李一楠

unread,
Nov 16, 2007, 9:46:01 AM11/16/07
to pon...@googlegroups.com
struct member has its own name 

Jian Wang

unread,
Nov 16, 2007, 10:00:51 AM11/16/07
to pon...@googlegroups.com
我觉得C++的语法没前途,属于一条道走到黑。
已经超级复杂了,还在往里面塞东西,而不做一下统一。
无数的力气花在了毫无意义的分析上面。难怪标准化委员会举步维艰。

在 07-11-16,李一楠<li_y...@163.com> 写道:

oldrev

unread,
Nov 16, 2007, 12:00:35 PM11/16/07
to pon...@googlegroups.com
一门语言如果符号太多就会显得很晦涩,如 Lisp、Haskell C/C++ 勉强也算,反
之,关键字太多就会变得很罗嗦,如 Pasca、Ada。
举个列子来说,C家族的 ?: 表达式在混代码里很不容易分辨,如果把 if 从语句
改成表达式 x = if(condition) 1 else 2; 就可以让代码看起来更清晰。毕竟 C
语言是70年代的产物,当时并没有语法高亮的编辑器、IDE、Intellisense等等,
而现在设计一门语言不可能不考虑这些因素。

Googol Lee

unread,
Nov 16, 2007, 9:32:18 PM11/16/07
to TopLanguage
Lisp的符号也多么?只知道点Sheme,印象里除了(),没有什么特殊的符号了。

On Nov 17, 1:00 am, oldrev <old...@gmail.com> wrote:
> 一门语言如果符号太多就会显得很晦涩,如 Lisp、Haskell C/C++ 勉强也算,反
> 之,关键字太多就会变得很罗嗦,如 Pasca、Ada。
> 举个列子来说,C家族的 ?: 表达式在混代码里很不容易分辨,如果把 if 从语句
> 改成表达式 x = if(condition) 1 else 2; 就可以让代码看起来更清晰。毕竟 C
> 语言是70年代的产物,当时并没有语法高亮的编辑器、IDE、Intellisense等等,
> 而现在设计一门语言不可能不考虑这些因素。
>
> On Sat, 2007-11-17 at 00:00 +0900, Jian Wang wrote:
> > 我觉得C++的语法没前途,属于一条道走到黑。
> > 已经超级复杂了,还在往里面塞东西,而不做一下统一。
> > 无数的力气花在了毫无意义的分析上面。难怪标准化委员会举步维艰。
>
> > 在 07-11-16,李一楠<li_yi...@163.com> 写道:

Jian Wang

unread,
Nov 17, 2007, 2:44:42 AM11/17/07
to pon...@googlegroups.com
C++是典型的IDE、Intellisense不友好语言。
在编辑.h的时候,由于不知道这个.h的前面会有些什么东西,所以.h中的内容是不可能正确解析的。
由于模板类的原因,在.h中的内容越来越多。从IDE的角度来看,非但没有进步,反而退步了。

在 07-11-17,Googol Lee<goog...@gmail.com> 写道:

yq chen

unread,
Nov 17, 2007, 3:18:30 AM11/17/07
to pon...@googlegroups.com
呵呵,我们喜欢用IDE。但是很多UNIX老牛不喜欢用IDE,认为IDE实际上是降低了开发效率。

在07-11-17,Jian Wang <oxygen.j...@gmail.com> 写道:

red...@gmail.com

unread,
Nov 17, 2007, 3:26:06 AM11/17/07
to pon...@googlegroups.com
嗯, 不怕, 以后的 cpu 很多 core, IDE 直接使用 10个 core 做即时程序编译,
根据语法树的结果来做这些工作 :)

Jian Wang 写道:

oldrev

unread,
Nov 17, 2007, 4:49:56 AM11/17/07
to pon...@googlegroups.com
我个人感觉 IDE 除了调试方便外没其他大用处。

在 2007-11-17六的 16:18 +0800,yq chen写道:
> 呵呵,我们喜欢用IDE。但是很多UNIX老牛不喜欢用IDE,认为IDE实际上是降低

wizard

unread,
Nov 17, 2007, 12:15:26 PM11/17/07
to pon...@googlegroups.com
调试方便难道不是最大的好处吗,对几乎所有程序员来说,调试的时间都要大于写代码的时间吧。
其实unix下可以自己搭建起来IDE环境的,无论是用emacs还是vi

 
在07-11-17,oldrev <old...@gmail.com> 写道:

Jian Wang

unread,
Nov 17, 2007, 11:04:01 PM11/17/07
to pon...@googlegroups.com
调试时间大于写代码的时间吗?我没有发现啊?
我做了6年的C++开发,调试时间只占了一小部分.大部分bug属于逻辑错误,不需要调试器的帮助就能修正.在有UintTest和assert的情况下,需要调试的就更少了.大部分属于看到BUG就知道为什么了.

不过小朋友里确实有盲目调试的.发现BUG后完全不思考就进行调试.调试时也没有方向,完全撞大运的方式,效率就非常低了.

在 07-11-18,wizard<klin...@gmail.com> 写道:

red...@gmail.com

unread,
Nov 18, 2007, 1:38:46 AM11/18/07
to pon...@googlegroups.com
调试时间大于写代码时间, 一般来说, 是没有想好就写, 或者是学的代码质量不够
的时候容易碰到.

我现在用 D 开发, 没有 IDE, 调试时间也只占了一小部分, 考虑结构和编码的时
间较多, 编写测试代码的时间也较多(我这里的代码需要可靠性较高, 所以我的
unittest 除了做 api 测试, 还做白盒测试, 针对内部的实现, 将各种边界条件都
进行测试), 等这些都准备好了, 最后的调试时间实际上并没有多长, 因为测试代
码可以抓住绝大多数 bug, 指示的位置很确定; 程序进行了修改, 改得不对, 测试
代码也不会放过. 当然这些测试代码也需要不少的维护时间, 但是, 这是自己的安
全降落伞, 时间是不能省的.

如果有 bug, 测试代码, assert 都没有抓住的的话 --- 我的程序编译的时候有
控制, 哪个模块, 调试输出到哪个级别, 可以进行控制, 打开合适的输出, 然后喂
它一堆数据, 喂到 bug 出来, 再分析 log, 很快就可以找到头绪了.

如果这样都很难调试的程序, 如果编码质量不会太糟糕, 那么多半就是程序结构太
过复杂了.

象以前我曾经写过一个程序, 运行几万次可能有一次出现问题, 老是找不出问题所
在, 搞来搞去实在没有办法, 最后放弃重写.

这个程序失败的原因是: 设计的时候, 想要追求很好的效率, 对象之间很多调用都
是直接调用, 造成调用 & 回调关系太过复杂, 再夹杂多线程的同步加锁, 最后复
杂到我自己都想不清楚, 如果多线程的时候, 这个路径这样执行, 那个路径同时这
样执行, 会不会出现问题, 这又怎么能够保证质量.

后来就吸取教训, 不搞这么复杂的动态结构的程序, 要调用对方, 但是 context
太复杂了? 那好办, 记录到一个延迟调用的队列中, 等到 context 简单的时候再
调用, 性能 ? 如果这个延迟登记队列不做动态内存分配的话, 性能的降低不会太多.

之后似乎就不曾出现过焦头烂额的情形了.

Jian Wang 写道:

Atry

unread,
Nov 18, 2007, 5:15:33 AM11/18/07
to pon...@googlegroups.com
我现在在 Linux ,不用 IDE 以后,调试所占的时间比例也很低。多写 ASSERT,找出出错的地方就很容易了。最重要的还是测试代码,我现在写测试代码所花的时间和功能编码的时间接近 1:1

在07-11-18,red...@gmail.com <red...@gmail.com> 写道:

Atry

unread,
Nov 18, 2007, 5:18:23 AM11/18/07
to pon...@googlegroups.com
因为学习 vi 或者 emacs 太费劲了,我用的是 gedit

在07-11-18,Atry <pop....@gmail.com> 写道:

oldrev

unread,
Nov 18, 2007, 6:20:52 AM11/18/07
to pon...@googlegroups.com
作为 vim 的铁杆粉丝,某推荐使用 vim 容易模式: evim,用 evim 命令启动的
vim 行为与一般编辑器无异,且能享用 vim 的各种高级功能。

Gedit 功能还勉强凑合,最近出了一个 Symbol Browser 插件,可以把文档里的方
法、类都列出来,支持30多种语言,可惜没有D。
http://www.micahcarrick.com/11-14-2007/gedit-symbol-browser-plugin.html

但是 Gedit 差的功能还是太多,什么括号匹配之类的都没有,如果不介意KDE的话
可以试试 Kate,功能要比 Gedit 强不少。

在 2007-11-18日的 18:18 +0800,Atry写道:

xbz

unread,
Nov 18, 2007, 8:44:14 AM11/18/07
to pon...@googlegroups.com
On Nov 18, 2007 6:18 PM, Atry <pop....@gmail.com> wrote:
> 因为学习 vi 或者 emacs 太费劲了,我用的是 gedit
>

vi还好吧,感觉看完那个tutorial以后就可以用了。
以后再慢慢扩展你所知道的命令。

Anson

unread,
Nov 18, 2007, 8:51:39 AM11/18/07
to pon...@googlegroups.com
我感觉用编辑器真的有点像使用计算机和计算器的关系。
如果你用的很少的话, 计算器也许就够了。
但是如果要复杂计算的话, 一个计算器就不够了。

编辑器也是这样, 在学会emacs以前。 觉得他那些快捷键什么太复杂了。
还不如不学, 就按原来的那种。
但是真正熟练了以后,
会发现, 太好用了。 效率真的提高了。

在07-11-18, xbz <xbz....@gmail.com> 写道:

YuchTing

unread,
Nov 19, 2007, 7:33:17 AM11/19/07
to TopLanguage
我是新丁,想问一下关于自动列出h文件里的函数的参数,列出structure成员,class成员等等,所谓的"智能感知"功能在vi和emacs有
么?

如果没于那些,关于函数的参数,函数名,大类的成员,是不是都要全记在脑子里呢?

On 11月17日, 下午5时49分, oldrev <old...@gmail.com> wrote:
> 我个人感觉 IDE 除了调试方便外没其他大用处。
>
> 在 2007-11-17六的 16:18 +0800,yq chen写道:
>
> > 呵呵,我们喜欢用IDE。但是很多UNIX老牛不喜欢用IDE,认为IDE实际上是降低
> > 了开发效率。
>
> > 在07-11-17,Jian Wang <oxygen.jian.w...@gmail.com> 写道:
> > C++是典型的IDE、Intellisense不友好语言。
> > 在编辑.h的时候,由于不知道这个.h的前面会有些什么东西,所
> > 以.h中的内容是不可能正确解析的。
> > 由于模板类的原因,在.h中的内容越来越多。从IDE的角度来看,
> > 非但没有进步,反而退步了。
>
> > 在 07-11-17,Googol Lee<googol...@gmail.com> 写道:

wizard

unread,
Nov 19, 2007, 1:05:53 PM11/19/07
to pon...@googlegroups.com
vim里面可以使用ctags,它可以让你方便的跳转到某个类、变量、函数的被定义的位置
cscope则可以查找到所有调用了某个类、变量、函数的位置。
不过搭车问一下,cscope对C++的支持如何?以前听说它是针对C编写的,对C++支持不好?

 
在07-11-19,YuchTing <YuCh...@gmail.com> 写道:
Reply all
Reply to author
Forward
0 new messages