[TL]C++处理大型项目的能力开始浮现了?{OT}

41 views
Skip to first unread message

up duan

unread,
Jul 5, 2010, 10:18:20 PM7/5/10
to TopLanguage

用C++重写的Compiz 0.9.0发布

前面还看到用C++重写GCC,为什么呢?
难道说用C++比用C更适合?why?
难道说真的是C++的大型项目能力真的比C强?或者是别的什么原因?

jinhu wang

unread,
Jul 6, 2010, 12:13:25 AM7/6/10
to pon...@googlegroups.com
哈哈,c和c++大战又来了。
多年后,我明白了遇到需要c项目不要说你会c++。
遇到需要c++的项目,你要说你很熟悉c&c++。

Fei Yan

unread,
Jul 6, 2010, 12:32:54 AM7/6/10
to pon...@googlegroups.com
不是说用c++重写GCC吧;只是编译时候用g++取代gcc,接受c++代码而已,差别很大的吧。

参考这里的Post:
以前的GCC只接受C代码,现在可以允许提交用C++写的代码而已;更多是一种对现实的折中措施。

在 2010年7月6日 上午10:18,up duan <fix...@gmail.com>写道:

sagasw

unread,
Jul 6, 2010, 12:45:32 AM7/6/10
to pon...@googlegroups.com
不知道回复的朋友有几个真正下载了compiz的代码稍微看看,然后再发表评论。

根据我对代码粗粗浏览,基本上就是把C++当做“具有类功能的C”来使用,没有什么复杂用法、模板技巧等等。
也称不上什么C++的成功,compiz现在的代码,用C一样可以完成,差别极小。

至于大型项目的成功?它代码量应该只能算中型项目吧。

------------------------------------------
blog: http://sunxiunan.com/
C++, Lua, living in Dalian
http://twitter.com/sagasw
------------------------------------------


2010/7/6 Fei Yan <skyscr...@gmail.com>
现在可以允许提交用C++写的代码而已;更多是一种对现实的折中

up duan

unread,
Jul 6, 2010, 3:14:15 AM7/6/10
to pon...@googlegroups.com


2010/7/6 sagasw <sag...@gmail.com>

不知道回复的朋友有几个真正下载了compiz的代码稍微看看,然后再发表评论。

根据我对代码粗粗浏览,基本上就是把C++当做“具有类功能的C”来使用,没有什么复杂用法、模板技巧等等。
也称不上什么C++的成功,compiz现在的代码,用C一样可以完成,差别极小。

至于大型项目的成功?它代码量应该只能算中型项目吧。


带类的C也不是C了呀。C++所支持的一大范式就是OO范式,就算没有用到继承,C对于ADT的支持也让人觉得很不自然。
我觉得问题的关键是为什么原来是C而现在要改成C++?显然是有足够的动力才能导致这样的转换,宁愿为此付出一定的代价。

BTW:不一定非得用“复杂”的C++用法才叫使用了C++吧。 

up duan

unread,
Jul 6, 2010, 3:21:58 AM7/6/10
to pon...@googlegroups.com


2010/7/6 Fei Yan <skyscr...@gmail.com>

不是说用c++重写GCC吧;只是编译时候用g++取代gcc,接受c++代码而已,差别很大的吧。

参考这里的Post:
以前的GCC只接受C代码,现在可以允许提交用C++写的代码而已;更多是一种对现实的折中措施。


The goal is a better compiler for users, not a C++ code base for its own sake
我怎么觉得这个Post不是你说的意思呢?完全没有为形势所迫不得不使用C++,而是积极主动的使用C++。
文中提到了要使用构造析构这类典型的C++特征,虽然限制了很多C++的“高级”特征,但是基本原因是为了方式C程序员的误用。yacc生成的编译器理论上是有内存泄漏的,就是因为C没有构造和析构导致的。
他们的目标是一个更好的编译器,是不是可以推论他们认为C++可以让他们作出一个更好的编译器。但是为什么?我觉得是C++表达概念比C清晰导致的。

Guanqun Lu

unread,
Jul 6, 2010, 4:04:37 AM7/6/10
to pon...@googlegroups.com
2010/7/6 up duan <fix...@gmail.com>:

1. gcc应该从4.0开始就采用手写的parser了吧,还用yacc么?
2. 我查了一下: 这里的 http://www.dazuiniu.com/blog/2010/06/02/gcc-use-cpp-to-develop.html
有几句话总结的还可以:
“他的意思现在不用太着急,没有必要为了改成 C++ 而改,而确实是有需求,
最希望看到的就是利用 C++ 来实现一些高级的,有用的特性,能够确实对 GCC 的用户有显著的帮助,
而并是一股脑的将 VEC_xxx 的类型全部改成 std::vector。”

你的这个问题问的很好,就是为什么他们认为C++会产生一个更好的编译器,至少是直觉上的。


--
Guanqun

up duan

unread,
Jul 6, 2010, 4:30:16 AM7/6/10
to pon...@googlegroups.com
http://gcc.gnu.org/wiki/CppConventions
从上面能看到一些端倪
这儿是一个解释,为什么使用C++

CXX16

unread,
Jul 6, 2010, 8:14:02 AM7/6/10
to pon...@googlegroups.com
��ʵ�������Ӧ����ΪʲôLLVM��CLANGҪ��C++��
On 2010/7/6 16:30, up duan wrote:
http://gcc.gnu.org/wiki/CppConventions
�������ܿ���һЩ����
�����һ�����ͣ�Ϊʲôʹ��C++

2010/7/6 Guanqun Lu <guanqun.lu@gmail.com>
2010/7/6 up duan <fix...@gmail.com>:
>
>
> 2010/7/6 Fei Yan <skyscr...@gmail.com>
>>
>> ����˵��c++��дGCC�ɣ�ֻ�DZ���ʱ����g++ȡ��gcc������c++������ѣ����ܴ�İɡ�
>> ������Post��
>> http://gcc.gnu.org/ml/gcc/2010-05/msg00705.html
>>
>> ��ǰ�ģǣã�ֻ���ܣô��룬���ڿ��������ύ�ãã���д�Ĵ�����ѣ������һ�ֶ���ʵ�����д�ʩ��

>
> The goal is a better compiler for users, not a C++ code base for its own
> sake
>
> ����ô�������Post������˵����˼�أ���ȫû��Ϊ�������Ȳ��ò�ʹ��C++�����ǻ�������ʹ��C++��
>
> �����ᵽ��Ҫʹ�ù�������������͵�C++��������Ȼ�����˺ܶ�C++�ġ��߼������������ǻ�ԭ����Ϊ�˷�ʽC����Ա�����á�yacc��ɵı��������� �������ڴ�й©�ģ�������ΪCû�й�����������µġ�
>
> ���ǵ�Ŀ����һ����õı��������Dz��ǿ�������������ΪC++��������������һ����õı�����������Ϊʲô���Ҿ�����C++�������C�����µġ�

1. gccӦ�ô�4.0��ʼ�Ͳ�����д��parser�˰ɣ�����yaccô��
2. �Ҳ���һ�£� ����� http://www.dazuiniu.com/blog/2010/06/02/gcc-use-cpp-to-develop.html
�м��仰�ܽ�Ļ����ԣ�
�������˼���ڲ���̫�ż���û�б�ҪΪ�˸ij� C++ ��ģ���ȷʵ��������
��ϣ���ľ������� C++ ��ʵ��һЩ�߼��ģ����õ����ԣ��ܹ�ȷʵ�� GCC ���û�������İ���
����һ���ԵĽ� VEC_xxx ������ȫ���ij� std::vector����

�����������ʵĺܺã�����Ϊʲô������ΪC++�����һ����õı�������������ֱ���ϵġ�


--
Guanqun


up duan

unread,
Jul 6, 2010, 8:35:36 PM7/6/10
to pon...@googlegroups.com


2010/7/6 CXX16 <cplus...@gmail.com>
其实这个问题应该问为什么LLVM和CLANG要用C++。


作为一个没有压力的新项目,选择什么语言主要取决于实施者的感觉了。所以LLVM采用C++不太能说明什么问题。但是传统的C项目改为C++就很有说服力了。 

Changsheng Jiang

unread,
Jul 6, 2010, 9:05:45 PM7/6/10
to pon...@googlegroups.com
赞同这句话.

在C编程时, 我最想用的 C++ 特性是模板式的代码生成, 这个可以减少重复代码量. 再一个是析构函数. 这个主要是在资源申请时指定资源释放, 并自动化.

模板在 C 里用宏比较丑陋. 我用过CPP之外的处理程序生成代码.

析构函数的自动化, 实在无法. 一个方法是将资源释放注册到一个栈式的地方, 栈弹出一层, 自动释放此层对应的所有资源.

反而觉得面向对象不是C++吸引C程序员的特性. 觉得面向接口更简单直接, 见过一些C++代码,  先声明接口 Interface, 再实现 Impl, 实是受强类型的面向对象所累.

不知大家欣赏的C++ - C 的特性是什么?

                                                     Changsheng Jiang


2010/7/7 up duan <fix...@gmail.com>

Kula

unread,
Jul 6, 2010, 9:14:54 PM7/6/10
to pon...@googlegroups.com
呵呵,20多年过去了,这个时候再来说c++处理大型项目的能力开始浮现,会不会太迟了。

其实花在关注c++上的时间,我们完全可以拿来关注golang.假以时日,等golang成熟了.大批大批的软件又会用golang 重写。



2010/7/7 Changsheng Jiang <jiang...@gmail.com>

Fei Yan

unread,
Jul 6, 2010, 9:18:24 PM7/6/10
to pon...@googlegroups.com
大批软件用golang重写的可能比较小,顶多用SWIG做跨语言接口就是了。
没有一定得trade-off考量,现有的大部分C代码会保持不动。

Guanqun Lu

unread,
Jul 6, 2010, 9:39:41 PM7/6/10
to pon...@googlegroups.com
golang首先一点就不支持windows系统,这个就会对它的大规模流行产生负作用。

2010/7/7 Kula <kula...@gmail.com>:

--
Guanqun

Fuzhou Chen

unread,
Jul 6, 2010, 9:51:58 PM7/6/10
to pon...@googlegroups.com
说句笑话啊,也许某一天我们回头看,没准就会发现golang不支持Windows,对推动Windows
的消亡产生了正面作用。:)

没有吵架的意思,呵呵。

2010/7/6 Guanqun Lu <guanq...@gmail.com>:

--
《采莲》·江南

为卿采莲兮涉水,为卿夺旗兮长战。为卿遥望兮辞宫阙,为卿白发兮缓缓歌。

另抄自蒜头的评论:http://www.douban.com/review/1573456/

  且祭一束紫琳秋,为一段落花流水的传说
  且饮一杯青花酒,为一场几多擦肩的错过
  且焚一卷旖旎念,为一腔抛付虚无的惜怜
  且歌一曲罢箜篌,为一刻良辰春宵的寂寞

Kula

unread,
Jul 6, 2010, 10:20:49 PM7/6/10
to pon...@googlegroups.com
现在已经支持了...童鞋要用发展的眼光来看问题啊

Guanqun Lu

unread,
Jul 6, 2010, 11:37:41 PM7/6/10
to pon...@googlegroups.com
看来我落伍了。呵呵

2010/7/7 Kula <kula...@gmail.com>:
> 现在已经支持了...童鞋要用发展的眼光来看问题啊
>
> 2010/7/7 Guanqun Lu <guanq...@gmail.com>

--
Guanqun

sagasw

unread,
Jul 7, 2010, 12:44:46 AM7/7/10
to pon...@googlegroups.com
无链接无真相啊


------------------------------------------
blog: http://sunxiunan.com/
C++, Lua, living in Dalian
http://twitter.com/sagasw
------------------------------------------


2010/7/7 Kula <kula...@gmail.com>

Kula

unread,
Jul 7, 2010, 12:53:22 AM7/7/10
to pon...@googlegroups.com
* runtime: additional Windows support (thanks Alex Brainman),
       correct fault for 16-bit divide on Leopard,
       fix 386 signal handler bug.


2010/7/7 sagasw <sag...@gmail.com>

Kula

unread,
Jul 7, 2010, 12:55:22 AM7/7/10
to pon...@googlegroups.com
我觉得现在已经很有必要跟进golang了。我写过两年c/c++.可能经验尚浅,但是在用c\c++的时候,遇到的一些问题,使我很难接受这两种语言,尤其是c++.
我享受的是快乐编程,但c++每次都能让我非常痛苦。


2010/7/7 Kula <kula...@gmail.com>

Fei Yan

unread,
Jul 7, 2010, 1:21:49 AM7/7/10
to pon...@googlegroups.com
golang还不是一个成熟的product,仅仅是experimental的,路还很长。业余关注尚可,花很多精力的话需要斟酌

Jeffrey Zhao

unread,
Jul 7, 2010, 1:25:44 AM7/7/10
to pon...@googlegroups.com
golang哪些地方让你快乐呢?
 
Jeffrey Zhao
Twitter: @jeffz_cn

Kula

unread,
Jul 7, 2010, 2:00:03 AM7/7/10
to pon...@googlegroups.com
我对任何类python的语言都持有好感. golang哪些地方让我快乐我说不上,毕竟没怎么接触。但c++哪些地方让我不快乐我能说很久很久

2010/7/7 Jeffrey Zhao <je...@live.com>

OxFAN

unread,
Jul 7, 2010, 2:20:08 AM7/7/10
to pon...@googlegroups.com
golang 还是个"类C"语言呢  

CXX16

unread,
Jul 7, 2010, 7:07:53 AM7/7/10
to pon...@googlegroups.com
插句话,go的库还是太少,于是又不得不退到包裹C库上。
而且现阶段go生产的程序运行速度也还是差一些。http://shootout.alioth.debian.org/u32/compare.php?lang=go
话题还是回到C++本身吧。
IMHO,早期gcc还是gnu c compiler时,恐怕没条件用c++写gcc吧;而现在gcc是gnu compiler collection了,人们有选择的可能性了,便开始考虑c++了。
同样可以体现在llvm和clang上,在GCC有C,C++,Fortran, Object-C的基础上,作者还是选择了C++,同样说明了C++有其优点,可以做到抽象性和速度在现实中的平衡。


On 2010/7/7 14:20, OxFAN wrote:
golang 还是个"类C"语言呢  

在 2010年7月7日 下午2:00,Kula <kula...@gmail.com>写 道:
我 对任何类python的语言都持有好感. golang哪些地方让我快乐我说不上,毕竟没怎么接触。但c++哪些地方让我不快乐我能说很久很久

2010/7/7 Jeffrey Zhao <je...@live.com>

golang哪些地方让你快乐呢?
 
Jeffrey Zhao
Twitter: @jeffz_cn
 
From: Kula
Sent: Wednesday, July 07, 2010 12:55 PM
Subject: Re: [TL]C++处理大型项目的能力开始浮现了?{OT}
 
我 觉得现在已经很有必要跟进golang了。我写过两年c/c++.可能经验尚浅,但是在用c\c++的时候,遇到的一些问题,使我很难接受这两种语言,尤 其是c++.

Linker

unread,
Jul 8, 2010, 9:21:51 AM7/8/10
to pon...@googlegroups.com
C++特性不能滥用。这个是最重要的。
其他,我觉得,都还好了。
新语言很难被大众接受,毕竟语言切换的成本太高。

> 2010/7/7 Guanqun Lu <guanq...@gmail.com>


>
>
>
> golang首先一点就不支持windows系统,这个就会对它的大规模流行产生负作用。
>
> 2010/7/7 Kula <kula...@gmail.com>:
>
>
> > 呵呵,20多年过去了,这个时候再来说c++处理大型项目的能力开始浮现,会不会太迟了。
>> 其实花在关注c++上的时间,我们完全可以拿来关注golang.假以时日,等golang成熟了.大批大批的软件又会用golang 重写。
>>
>>
>> 2010/7/7 Changsheng Jiang <jiang...@gmail.com>
>>>
>>> 赞同这句话.
>>>
>>> 在C编程时, 我最想用的 C++ 特性是模板式的代码生成, 这个可以减少重复代码量. 再一个是析构函数.
> 这个主要是在资源申请时指定资源释放,
>>> 并自动化.
>>>
>>> 模板在 C 里用宏比较丑陋. 我用过CPP之外的处理程序生成代码.
>>>
>>> 析构函数的自动化, 实在无法. 一个方法是将资源释放注册到一个栈式的地方, 栈弹出一层, 自动释放此层对应的所有资源.
>>>
>>> 反而觉得面向对象不是C++吸引C程序员的特性. 觉得面向接口更简单直接, 见过一些C++代码,  先声明接口
> Interface, 再实现
>>> Impl, 实是受强类型的面向对象所累.
>>>
>>> 不知大家欣赏的C++ - C 的特性是什么?
>>>
>>>
> Changsheng Jiang
>>>
>>>
>>> 2010/7/7 up duan <fix...@gmail.com>
>>>>
>>>>
>>>> 2010/7/6 CXX16 <cplus...@gmail.com>
>>>>>
>>>>> 其实这个问题应该问为什么LLVM和CLANG要用C++。
>>>>>
>>>>
>>>>
> 作为一个没有压力的新项目,选择什么语言主要取决于实施者的感觉了。所以LLVM采用C++不太能说明什么问题。但是传统的C项目改为C++就很有说服力
> 了。
>>>
>>
>>
>
>
>
>
>
> --
> Guanqun
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

--
Regards,
Linker Lin
linker...@gmail.com

机械唯物主义 : linjunhalida

unread,
Jul 8, 2010, 9:29:34 AM7/8/10
to pon...@googlegroups.com
|毕竟语言切换的成本太高
对于我来说,如果没有什么革命性的特性,支持LIBC,或者python库,应该一天就可以搞定了。

2010/7/8 Linker <linker...@gmail.com>

莫华枫

unread,
Jul 9, 2010, 2:57:27 AM7/9/10
to pon...@googlegroups.com
C++优点和缺点一样明显。
严格地讲,C++的优点也不是什么特别伟大的东西,只是顺应了一些本质规律,给予更多的选择,而不是拘泥于某种单一的范式。
C++的缺点则来源广泛,一部分来自C,比如non-lr的语法,隐式的类型转换,资源管理困难,陈旧的编译模型等等。有些来自于过于机巧的设计,比如默认的隐式类型转换构造和操作符,操作符","的重载等等。有些来自于委员会的扯皮,比如ABI问题,逻辑操作的执行次序问题等等。以及添油式的设计,比如GP作为后加入的特性无法同早期OOP特性完美地协调。
BS创建C++的时候试图利用OOP消除C存在的问题。但是全面兼容C减少了推广的困难,却导致了语法上的混乱。毕竟C是一门独立完备的语言,设计时也没有考虑未来的特性扩展,使得原本non-lr的语法更加复杂,编译时间暴涨,而编译器的开发更加困难。
OOP的引入当时看起来是对C语言很好的扩充,但现在看来OOP反而引发了很多问题。问题的根源在于OOP并非完善的抽象体系。相反,OOP只能算作一个半熟的解决方案。在C++领域中,OOP有广义和狭义之分。广义上,OOP包括OB、重载和动多态,甚至有人将GP的一些特性算作OOP范畴。狭义上,OOP单指动多态。真正有问题的是狭义OOP,即动多态。
OB是C++最重要的特性,这是一个完全正面的特性。封装是所有抽象的基础。在此基础上增设的RAII(即自动对象)是C++相对于C最好的补充。RAII允许进入和离开一个scope时执行特定的操作,这是一种极好的资源和状态管理的手段。
继承是依附于封装的特性,但继承存在两重性。作为代码重用机制,很大地提高了开发效率。但另一方面,继承却不恰当地成为OOP的动多态基础。
OOP(以下OOP仅指动多态)是一种有缺陷的抽象机制,是基于类型和继承的多态。但其中存在根本性的问题。举个例子,计算金额,我们会说把单价*数量。用程序员的语言,就是:一个浮点数*一个整数。这是抽象的说法,说这句话的时候我们没有明确指定单价是什么样的浮点数,是single还是double,什么样的整数,是4字节还是8字节。这是很自然的逻辑。但是在OOP中无法这样描述。我们只能说:一个从float类型上继承的数*一个从integer类型上继承的数。因为在OOP中是通过一种类型来描述一组类型的,两者的联系就是继承。这中间的问题在于,继承是一种很强的耦合关系,依赖于这种关系的抽象体系是侵入的。由于继承关系的存在,接口成为了类型的一部分,一个类型所支持的接口,必须在定义时决定,以后无法扩展。即便一个类型同一个接口完全一致,只要没有继承关系,就不是一家人。形象地说,老虎A,无论多么像老虎B,只要不是老虎B的崽,它就不是老虎。这显然是荒谬的。问题就是我们用一只老虎来指代老虎这个物种。OOP却是这么做的,用一个类型来抽象一组类型。
更糟糕的是,C++引入OOP还带来了意想不到的问题。首当其冲的是对象切割问题:
class A
{...};

class B : public A
{...};

B arrayB[10];
A pa = arrayB;
pa[3]->...   //你访问的是什么?
很显然,最后那行代码是一个错误的访问。pa[3]是按A计算的偏移,而pa真正指向的是B的数组,两者的偏移可能是不一样的。问题的根本是为了实现动多态,继承类指针可以隐式地转换成基类的指针。而C的数组和指针又是等价的。
从这一点上说,C是不适合引入OOP机制的。C太底层,而OOP又不完备。
但另一种抽象机制——GP的引入却是非常恰当的。模板,无论是类模板还是函数模板,提供了一套完全独立于类型的抽象系统,很好地回避了“老虎不是老虎”的问题。而在C++0x中引入未果的concept则是GP机制的一个重要的完善。
OOP和GP两种机制分别应对动多态和静多态。看似相互补充,各有分工,但实际上凭空增加了语言的复杂性,难于融合。OOP本身的缺陷加剧了问题的混乱。一种语言只应当有一种抽象体系。对C而言,如果要增加抽象体系,GP比OOP更合适。GP目前只有静多态。但是随着concept的完善,runtime concept也浮出水面,进而促使GP具备动态的抽象能力。这样程序员就不会迷失在两套不同的抽象体系中。
GP还有能力消除C语言的某些缺陷。比如,C不能算真正意义上的强类型,因为存在隐式类型转换,容易造成编码的错误。这一点在当年C vs Pascal的论战中是重要的把柄。但如果没有这些转换,又无法获得足够的灵活性。C++对C所作的扩展并未解决这些问题,反而增加了其他更多的问题,特别是依赖于继承的隐式类型转换。而GP的抽象体系却可以在强化C的类型系统的情况下,提供足够的灵活性。这一点在Ada上就有所体现。Ada是先有GP(Ada83),后有OOP(Ada95)。如果Ada能够向runtime GP,而非时髦的OOP发展,或许更有意义。



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

dachuan lin

unread,
Jul 9, 2010, 9:58:44 AM7/9/10
to pon...@googlegroups.com
严格来说,C和C++用来解决代码生成的技术,其实是走错了方向。
1、对于C来说,代码生成的方式主要是靠宏,其带来的问题就不用说了;
2、C++的创造者发现了宏的问题,其改善的方法,一个是发明了继承,不过这个其实只是擦擦边而已,真正接触到核心的还是模板(template)的引入。
但是,这两者都是在歧路上越走越远。真正的解决之道,一方面如C#引入的,attribute,特性,另一方面,其实就应该光明正大的引入代码生成语言(不错,make configuration就是解决之道,可惜的是没有真正和C完全融合,并形成标准),以及预编译的模板库(或者类型库)。
其实工程界早都已经自觉不自觉的引入了这些技术,比如windows下微软的类型库,以及广泛使用的make等技术,只是都不敢或者没想到把这些完全融合在一起。
在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
1、类似C的语法;
2、强类型语言,但是可以静态自动类型推断;
3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;
4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
5、预编译模板库;
6、完整的静态接口设计;
7、原生支持并行;
8、原生支持GC;

up duan

unread,
Jul 9, 2010, 10:22:42 AM7/9/10
to pon...@googlegroups.com


2010/7/9 dachuan lin <lindach...@gmail.com>

严格来说,C和C++用来解决代码生成的技术,其实是走错了方向。
1、对于C来说,代码生成的方式主要是靠宏,其带来的问题就不用说了;
2、C++的创造者发现了宏的问题,其改善的方法,一个是发明了继承,不过这个其实只是擦擦边而已,真正接触到核心的还是模板(template)的引入。
但是,这两者都是在歧路上越走越远。真正的解决之道,一方面如C#引入的,attribute,特性,另一方面,其实就应该光明正大的引入代码生成语言(不错,make configuration就是解决之道,可惜的是没有真正和C完全融合,并形成标准),以及预编译的模板库(或者类型库)。
其实工程界早都已经自觉不自觉的引入了这些技术,比如windows下微软的类型库,以及广泛使用的make等技术,只是都不敢或者没想到把这些完全融合在一起。
不觉得模板是入歧途。也不觉得Attribute就是真正的解决之道。能给出说明为什么吗?
宏是一个非常好的代码生成技术。当然,C的宏由于自身的一些限制导致不够理想,但是m4明显舒服的多,更别说scheme了。
你说的“类型库”就是“预编译的模板库”么?不太清楚你的标的是什么。不过业界早已把make技术用于代码生成了。 
在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
1、类似C的语法;
C的语法是如此的不清晰,还是不类似的好一些。 
2、强类型语言,但是可以静态自动类型推断;
好特性。好难。Haskell和OCaml以及Scala都有这些设施。 
3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;
至少现在的Java和.Net平台都提供了Compiler访问的API。而且编译器作为应用的一部分逻辑上需要虚拟机支撑,否则应用不能部署。而部署虚拟机本身就是一个问题。 
4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
LLVM。 
5、预编译模板库;
……,不是很清楚这是什么意思,你是指C++的模板么?或许是指.NET的Generic? 
6、完整的静态接口设计;
这年头,动态接口才是新闻。 
7、原生支持并行;
如果是通用目的的并行,现在的Thread和Lock就完全支持了。而且也似乎只有它们才支持通用目的的并行。如果是特定场景下的并行,似乎不应该作为语言的特性存在吧。 
8、原生支持GC;
GC似乎仍然达不到通用目的。仍有适用场景。最好是可以通过声明允许或者禁止的。 

Milo Yip

unread,
Jul 9, 2010, 11:49:26 AM7/9/10
to pon...@googlegroups.com
C# 2.0 的 var 和 C++0x 的 auto 可滿足你對靜態自動類型推導的要求麼?
不理解"完整的静态接口设计"

在 2010年7月9日下午9:58,dachuan lin <lindach...@gmail.com> 寫道:
> 严格来说,C和C++用来解决代码生成的技术,其实是走错了方向。
> 1、对于C来说,代码生成的方式主要是靠宏,其带来的问题就不用说了;
> 2、C++的创造者发现了宏的问题,其改善的方法,一个是发明了继承,不过这个其实只是擦擦边而已,真正接触到核心的还是模板(template)的引入。
> 但是,这两者都是在歧路上越走越远。真正的解决之道,一方面如C#引入的,attribute,特性,另一方面,其实就应该光明正大的引入代码生成语言(不错,make
> configuration就是解决之道,可惜的是没有真正和C完全融合,并形成标准),以及预编译的模板库(或者类型库)。
> 其实工程界早都已经自觉不自觉的引入了这些技术,比如windows下微软的类型库,以及广泛使用的make等技术,只是都不敢或者没想到把这些完全融合在一起。
> 在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
> 1、类似C的语法;
> 2、强类型语言,但是可以静态自动类型推断;
> 3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;
> 4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
> 5、预编译模板库;
> 6、完整的静态接口设计;
> 7、原生支持并行;
> 8、原生支持GC;

--
Milo Yip

Twitter @miloyip
http://www.cnblogs.com/miloyip/
http://miloyip.seezone.net/

Jeffrey Zhao

unread,
Jul 9, 2010, 12:07:24 PM7/9/10
to pon...@googlegroups.com
�������㲻�˰ɣ�C# 2.0��3.0���Ƶ��IJ����ף�����Haskell�������ó��ס���


Jeffrey Zhao
Blog: http://blog.zhaojie.me/
Twitter: @jeffz_cn

-----Original Message-----
From: Milo Yip
Sent: Friday, July 09, 2010 11:49 PM
To: pon...@googlegroups.com

Subject: Re: [TL]C++���������Ŀ��������ʼ�����ˣ�{OT}

C# 2.0 �� var �� C++0x �� auto �ɝM���㌦�o�B�Ԅ�����ƌ���Ҫ���N?
�����"����ľ�̬�ӿ����"

�� 2010��7��9������9:58��dachuan lin <lindach...@gmail.com> ������
> �ϸ���˵��C��C++�������������ɵļ�������ʵ���ߴ��˷���
> 1������C��˵��������ɵķ�ʽ��Ҫ�ǿ��꣬�����������Ͳ���˵�ˣ�
> 2��C++�Ĵ����߷����˺�����⣬����Ƶķ�����һ���Ƿ����˼̳У����������ʵֻ�Dz����߶��ѣ�����Ӵ������ĵĻ���ģ�壨template�������롣
> ���ǣ������߶�������·��Խ��ԽԶ������Ľ��֮����һ������C#����ģ�attribute�����ԣ���һ���棬��ʵ��Ӧ�ù��������������������ԣ����?make
> configuration���ǽ��֮������ϧ����û�������C��ȫ�ںϣ����γɱ�׼�����Լ�Ԥ�����ģ��⣨�������Ϳ⣩��
> ��ʵ���̽��綼�Ѿ��Ծ����Ծ�����������Щ����������windows��΢������Ϳ⣬�Լ��㷺ʹ�õ�make�ȼ�����ֻ�Ƕ����һ���û�뵽����Щ��ȫ�ں���һ��
> ���ҵ������У����ϣ���ܹ���һ�����ԣ�������ȫʵ�����µĹ��ܣ�
> 1������C������
> 2��ǿ�������ԣ����ǿ��Ծ�̬�Զ������ƶϣ�
> 3������������֣���ɽ׶����Ժ����н׶����ԣ�������������Ϊ����������У�
> 4������ɿ��ʱ�򣬴����������������Ϣ�����linkΪexeʱ���Ծ������Ż���
> 5��Ԥ����ģ��⣻
> 6������ľ�̬�ӿ���ƣ�
> 7��ԭ��֧�ֲ��У�
> 8��ԭ��֧��GC��

Yingjie XU

unread,
Jul 9, 2010, 12:24:07 PM7/9/10
to pon...@googlegroups.com
要支持强类型推导的话
一定会损失一些特性的吧
像是隐式类型转换或者函数重载之类的

2010/7/9 Jeffrey Zhao <je...@live.com>
估计满足不了吧,C# 2.0和3.0都推导的不彻底,还是Haskell这种来得彻底……



Jeffrey Zhao
Blog: http://blog.zhaojie.me/
Twitter: @jeffz_cn

-----Original Message----- From: Milo Yip
Sent: Friday, July 09, 2010 11:49 PM

To: pon...@googlegroups.com
Subject: Re: [TL]C++处理大型项目的能力开始浮现了?{OT}

C# 2.0 的 var 和 C++0x 的 auto 可滿足你對靜態自動類型推導的要求麼?
不理解"完整的静态接口设计"

在 2010年7月9日下午9:58,dachuan lin <lindach...@gmail.com> 寫道:
严格来说,C和C++用来解决代码生成的技术,其实是走错了方向。
1、对于C来说,代码生成的方式主要是靠宏,其带来的问题就不用说了;
2、C++的创造者发现了宏的问题,其改善的方法,一个是发明了继承,不过这个其实只是擦擦边而已,真正接触到核心的还是模板(template)的引入。
但是,这两者都是在歧路上越走越远。真正的解决之道,一方面如C#引入的,attribute,特性,另一方面,其实就应该光明正大的引入代码生成语言(不错,make
configuration就是解决之道,可惜的是没有真正和C完全融合,并形成标准),以及预编译的模板库(或者类型库)。
其实工程界早都已经自觉不自觉的引入了这些技术,比如windows下微软的类型库,以及广泛使用的make等技术,只是都不敢或者没想到把这些完全融合在一起。
在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
1、类似C的语法;
2、强类型语言,但是可以静态自动类型推断;
3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;
4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
5、预编译模板库;
6、完整的静态接口设计;
7、原生支持并行;
8、原生支持GC;




--
Yingjie XU
Département d'informatique
École Normale Supérieure
45 rue d'Ulm
F-75230 Paris Cedex 05

"If you received this communication by mistake,
please don't forward it to anyone else (it may contain
confidential or privileged information), please erase
all copies of it, including all attachments, and please
let the sender know it went to the wrong person.
Thanks."

Jeffrey Zhao

unread,
Jul 9, 2010, 12:37:57 PM7/9/10
to pon...@googlegroups.com
支持强类型推导,不代表不不支持显式的类型指定啊,呵呵
 
Jeffrey Zhao
Twitter: @jeffz_cn

dachuan lin

unread,
Jul 9, 2010, 1:26:33 PM7/9/10
to pon...@googlegroups.com
在 2010年7月9日 下午10:22,up duan <fix...@gmail.com>写道:


2010/7/9 dachuan lin <lindach...@gmail.com>

严格来说,C和C++用来解决代码生成的技术,其实是走错了方向。
1、对于C来说,代码生成的方式主要是靠宏,其带来的问题就不用说了;
2、C++的创造者发现了宏的问题,其改善的方法,一个是发明了继承,不过这个其实只是擦擦边而已,真正接触到核心的还是模板(template)的引入。
但是,这两者都是在歧路上越走越远。真正的解决之道,一方面如C#引入的,attribute,特性,另一方面,其实就应该光明正大的引入代码生成语言(不错,make configuration就是解决之道,可惜的是没有真正和C完全融合,并形成标准),以及预编译的模板库(或者类型库)。
其实工程界早都已经自觉不自觉的引入了这些技术,比如windows下微软的类型库,以及广泛使用的make等技术,只是都不敢或者没想到把这些完全融合在一起。
不觉得模板是入歧途。也不觉得Attribute就是真正的解决之道。能给出说明为什么吗?
模板是为了解决代码生成的问题,但是却只走了一半的路,而且和“运行代码”结合得太紧密,变得非常的难看,难写。
其实模板只要能够描述代码生成的方式就可以了,而这些完全可以由编译系统来完成。
举个例子
,比如在类型推断中,常常会有很多的方式来判断类型是原生数据类型呢?还是自定义类型?这些信息,其实编译器都知道,只需要建立一种“编译器语言”,就可以指定如何编译了,
有点类似下面的代码:
[@gen: type TYPE]
int max(TYPE &a1, TYPE &a2)
{
    [@gen: if TYPE is NUMBER then ]
        return (a1>a2)? a1: a2;
    [@gen: elseif TYPE is CLASS && TYPE has @memfun: compare then]
        return a1.compare(a2);
    [@gen: else]
       throw std::exception::member_not_defined;
    [@gen: endif]
}
上面的代码中,[@gen]部分表示“生成代码”,其信息可以从编译器对代码的静态分析得到,相当于C中的预编译,但是由于其完全和“运行代码”一体化设计,
所以其功能比简单的代码替换要强得多,可以完成以下功能:
1、自动生成一个代码模板,也就是已经预编译好三段的函数代码;
2、在编译链接时,实际的调用代码中用实际的类型 进行 调用 的时候,编译器会决断其类型是哪一种,从而自动将所需的代码链入;
3、不但可以分辨是否普通数值类型(比如整数、浮点),而且可以分辨是否是一个类,这个类是否含有某个成员,注意这些都是静态的,也就是完全不需要定义是否
是继承或虚函数,因为类的信息在编译的时候都保存起来了。
没错,我知道这个和concept很相近,但是C++中的concept搞得很复杂,我不知道为什么,其实如果换个角度,把concept当作是编译器的指令代码,可以有特权来访问编译的
时候生成的类型完整信息的话,其实现会非常简单。
   
宏是一个非常好的代码生成技术。当然,C的宏由于自身的一些限制导致不够理想,但是m4明显舒服的多,更别说scheme了。
你说的“类型库”就是“预编译的模板库”么?不太清楚你的标的是什么。不过业界早已把make技术用于代码生成了。 
类型库指的是你创建的库中所有的类型和函数的完整信息,比如类名,成员变量名称、类型,成员函数名称、参数、返回值、虚实等等。
同时,如果是模板类型的话,则会包含多重实践的代码;这个有点像delphi的单元+tlb
 
在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
1、类似C的语法;
C的语法是如此的不清晰,还是不类似的好一些。 
简洁还是类C的好。当然新语言可以完全不考虑缺省类型自动转换等混淆的部分;
 
2、强类型语言,但是可以静态自动类型推断;
好特性。好难。Haskell和OCaml以及Scala都有这些设施。 
3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;
至少现在的Java和.Net平台都提供了Compiler访问的API。而且编译器作为应用的一部分逻辑上需要虚拟机支撑,否则应用不能部署。而部署虚拟机本身就是一个问题。 
这个功能我觉得可以实现 嵌入式的脚本编译,脚本相当于是自己的语言。
为什么要虚拟机呢?比如在windows下生成的程序,自带windows下的compiler和linker,你可以在程序运行中,自动或由用户输入生成一段代码,然后调用附带的compiler编译到内存中,
然后返回函数指针,即可以进行调用。
4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
LLVM。 
是个好选择。是否可以用于代码生成?
5、预编译模板库;
……,不是很清楚这是什么意思,你是指C++的模板么?或许是指.NET的Generic? 
参见上面的例子。其实就是根据不同的生成选项 先 生成不同的代码 集结成库,方便快速进行链接。
当然其大小可能很大,但是比源码要快,同时在生成实际代码的时候只链入实际的部分。
6、完整的静态接口设计;
这年头,动态接口才是新闻。 
这个是和C++和JAVA的接口相比较的,实际上是在编译的时候进行多态,所以完全不需要继承和虚函数。
7、原生支持并行;
如果是通用目的的并行,现在的Thread和Lock就完全支持了。而且也似乎只有它们才支持通用目的的并行。如果是特定场景下的并行,似乎不应该作为语言的特性存在吧。 
我觉得并行代码应该在底层支持映射到不同平台,同时定义一些原子级的变量、锁和操作
8、原生支持GC;
GC似乎仍然达不到通用目的。仍有适用场景。最好是可以通过声明允许或者禁止的。 
这个确实。可以禁止。

up duan

unread,
Jul 9, 2010, 1:34:58 PM7/9/10
to pon...@googlegroups.com


2010/7/10 dachuan lin <lindach...@gmail.com>
max(a, b) {

dachuan lin

unread,
Jul 9, 2010, 1:51:53 PM7/9/10
to pon...@googlegroups.com
在 2010年7月9日 下午11:49,Milo Yip <mil...@gmail.com>写道:
C# 2.0 的 var 和 C++0x 的 auto 可滿足你對靜態自動類型推導的要求麼?
差不多。
不理解"完整的静态接口设计"
比如下面的代码:
[@gen: type TYPE is CLASS]
interface COMPARE {
    int  compare( TYPE &a1, TYPE &a2);
}
class COMPLEX
{
    int compare ( COMPLEX &a, COMPLEX &b){ ... }

}
[@gen: type TYPE]
int max(TYPE &a1, TYPE &a2)
{
    [@gen: if TYPE is NUMBER then ]
        return (a1>a2)? a1: a2;
    [@gen: elseif TYPE is CLASS && TYPE has @interface:COMPARE then]

        return a1.compare(a2);
    [@gen: else]
       throw std::exception::member_not_defined;
    [@gen: endif]
}
void fun1()
{
   COMPLEX a, b;
   return max(a, b);
}

可以看到,COMPLEX类完全不需要从COMPARE继承,也不需要任何的虚函数,在编译的时候, 自动会检查是否包含了interface的相关函数或成员,如果是就自动链入
其相对应的函数。要这么做,必须在编译的时候,编译器完全知道所有相关类型的信息。

up duan

unread,
Jul 9, 2010, 2:02:14 PM7/9/10
to pon...@googlegroups.com


2010/7/10 dachuan lin <lindach...@gmail.com>
max(a, b) {
    if a > b
        return a
    else
        return b
}

这是无类型语言的基本写法。如果是类型语言,采用
sametypeof a max(a is comparable, b sametypeof a) {
    if a > b
        return a
    else
        return b
}
Eiffel就可以做到。C++可以通过type traits手动做到。
你希望这些代码编译为某种形式(AST?),在调用的时候进行参数化类型的替换。这个是把编译阶段的事情放到连接阶段去做了。严格的说,这样子其实不需要编译了。

宏是一个非常好的代码生成技术。当然,C的宏由于自身的一些限制导致不够理想,但是m4明显舒服的多,更别说scheme了。
你说的“类型库”就是“预编译的模板库”么?不太清楚你的标的是什么。不过业界早已把make技术用于代码生成了。 
类型库指的是你创建的库中所有的类型和函数的完整信息,比如类名,成员变量名称、类型,成员函数名称、参数、返回值、虚实等等。
同时,如果是模板类型的话,则会包含多重实践的代码;这个有点像delphi的单元+tlb
 
Java和.NET似乎都满足这个条件。除了你说的模板。
 
在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
1、类似C的语法;
C的语法是如此的不清晰,还是不类似的好一些。 
简洁还是类C的好。当然新语言可以完全不考虑缺省类型自动转换等混淆的部分;
 
C不仅仅是自动类型转换导致的不清晰。它本身的语法就非常不规整,导致非常不清晰,很多时候需要超越语法规则的元规则才能解决二义性。
2、强类型语言,但是可以静态自动类型推断;
好特性。好难。Haskell和OCaml以及Scala都有这些设施。 
3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;
至少现在的Java和.Net平台都提供了Compiler访问的API。而且编译器作为应用的一部分逻辑上需要虚拟机支撑,否则应用不能部署。而部署虚拟机本身就是一个问题。 
这个功能我觉得可以实现 嵌入式的脚本编译,脚本相当于是自己的语言。
为什么要虚拟机呢?比如在windows下生成的程序,自带windows下的compiler和linker,你可以在程序运行中,自动或由用户输入生成一段代码,然后调用附带的compiler编译到内存中,
然后返回函数指针,即可以进行调用。
如果你的程序需要部署到linux下呢?你的compiler和linker还能用么? 

4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
LLVM。 
是个好选择。是否可以用于代码生成?
5、预编译模板库;
……,不是很清楚这是什么意思,你是指C++的模板么?或许是指.NET的Generic? 
参见上面的例子。其实就是根据不同的生成选项 先 生成不同的代码 集结成库,方便快速进行链接。
当然其大小可能很大,但是比源码要快,同时在生成实际代码的时候只链入实际的部分。

6、完整的静态接口设计;
这年头,动态接口才是新闻。 
这个是和C++和JAVA的接口相比较的,实际上是在编译的时候进行多态,所以完全不需要继承和虚函数。
看看前面的那个例子max,仔细想想,你就会知道:继承是很多重用的根本。虚函数是一种实现机制,跟继承不可同日而语。编译时就可以确定某些Override的行为具体落实到那个代码片段上,运行时自然就可以直接调用。其实Java在这一点上已经做得非常好了,不过由于Java的优化是JIT的,你或许会觉得还是占用了运行时间,那么Eiffel的完全编译时搞定就能满足你了【完全不用修改现在的连接器】。 
7、原生支持并行;
如果是通用目的的并行,现在的Thread和Lock就完全支持了。而且也似乎只有它们才支持通用目的的并行。如果是特定场景下的并行,似乎不应该作为语言的特性存在吧。 
我觉得并行代码应该在底层支持映射到不同平台,同时定义一些原子级的变量、锁和操作
这需要一个比较庞大的运行时,或许叫虚拟机更恰当一点。 

up duan

unread,
Jul 9, 2010, 2:06:31 PM7/9/10
to pon...@googlegroups.com


2010/7/10 dachuan lin <lindach...@gmail.com>



在 2010年7月9日 下午11:49,Milo Yip <mil...@gmail.com>写道:

C# 2.0 的 var 和 C++0x 的 auto 可滿足你對靜態自動類型推導的要求麼?
差不多。
不理解"完整的静态接口设计"
比如下面的代码:
[@gen: type TYPE is CLASS]
interface COMPARE {
    int  compare( TYPE &a1, TYPE &a2);
}
class COMPLEX
{
    int compare ( COMPLEX &a, COMPLEX &b){ ... }

}
[@gen: type TYPE]
int max(TYPE &a1, TYPE &a2)
{
    [@gen: if TYPE is NUMBER then ]
        return (a1>a2)? a1: a2;
    [@gen: elseif TYPE is CLASS && TYPE has @interface:COMPARE then]

        return a1.compare(a2);
    [@gen: else]
       throw std::exception::member_not_defined;
    [@gen: endif]
}
void fun1()
{
   COMPLEX a, b;
   return max(a, b);
}

可以看到,COMPLEX类完全不需要从COMPARE继承,也不需要任何的虚函数,在编译的时候, 自动会检查是否包含了interface的相关函数或成员,如果是就自动链入
其相对应的函数。要这么做,必须在编译的时候,编译器完全知道所有相关类型的信息。


go语言就不需要程序员显式的【也不能】给出类型之间的关系,而是由编译器自己去判别这一点。
关于>和compare,只不过是名字不同罢了,在同一个项目中要保持一致性。其实严格的说compare要处理> < =等,但你这儿似乎是一个功能。

dachuan lin

unread,
Jul 9, 2010, 2:29:05 PM7/9/10
to pon...@googlegroups.com
如果有多个接口,或者不同类的相类似的处理函数的名称不一样(这在共用多个第三方的库的时候很常见),就很适合了。


dachuan lin

unread,
Jul 9, 2010, 2:51:47 PM7/9/10
to pon...@googlegroups.com
C++的type traits之丑陋和局限,是远不能处理以上问题的。比如某些类比较的函数是compare,某些是其他的名称呢(复用第三方代码时)?而且trait必须是继承类,如果我只有最简单的没有虚函数的类呢(只要满足其对成员函数的需求即可)?
其实类型的信息都在编译器中的数据库里,完全可以使用类似的静态查询的办法来在编译器就能判断是否满足条件,从而可以得到更为准确的错误定位和更清晰的代码,而且也减少了很多的包装层。
没错,“这些代码编译为某种形式(AST?),在调用的时候进行参数化类型的替换。”,这些操作可以集中进行,以后就可以极大的减少编译的时间。

宏是一个非常好的代码生成技术。当然,C的宏由于自身的一些限制导致不够理想,但是m4明显舒服的多,更别说scheme了。
你说的“类型库”就是“预编译的模板库”么?不太清楚你的标的是什么。不过业界早已把make技术用于代码生成了。 
类型库指的是你创建的库中所有的类型和函数的完整信息,比如类名,成员变量名称、类型,成员函数名称、参数、返回值、虚实等等。
同时,如果是模板类型的话,则会包含多重实践的代码;这个有点像delphi的单元+tlb
 
Java和.NET似乎都满足这个条件。除了你说的模板。
java等问题是,编译好的东西(比如库)包含 太多的信息,并会直接传递到最后的运行程序中。这造成了资源的浪费。我希望的是在生成lib的时候包含充分的信息,但最后link的时候尽可能的去除。
 
在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
1、类似C的语法;
C的语法是如此的不清晰,还是不类似的好一些。 
简洁还是类C的好。当然新语言可以完全不考虑缺省类型自动转换等混淆的部分;
 
C不仅仅是自动类型转换导致的不清晰。它本身的语法就非常不规整,导致非常不清晰,很多时候需要超越语法规则的元规则才能解决二义性。
没办法,C语言已经成为事实的规范了。学院派对此不满意,但是实际实现还是不会有太多的二义性的。
 
2、强类型语言,但是可以静态自动类型推断;
好特性。好难。Haskell和OCaml以及Scala都有这些设施。 
3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;
至少现在的Java和.Net平台都提供了Compiler访问的API。而且编译器作为应用的一部分逻辑上需要虚拟机支撑,否则应用不能部署。而部署虚拟机本身就是一个问题。 
这个功能我觉得可以实现 嵌入式的脚本编译,脚本相当于是自己的语言。
为什么要虚拟机呢?比如在windows下生成的程序,自带windows下的compiler和linker,你可以在程序运行中,自动或由用户输入生成一段代码,然后调用附带的compiler编译到内存中,
然后返回函数指针,即可以进行调用。
如果你的程序需要部署到linux下呢?你的compiler和linker还能用么? 
老兄你还是以java或C#的思维来考虑了。我设想的是类似C这样的源代码移植,当然在compile的时候就已经知道目标平台了,那么直接附带该平台的compiler有什么问题呢?

4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
LLVM。 
是个好选择。是否可以用于代码生成?
5、预编译模板库;
……,不是很清楚这是什么意思,你是指C++的模板么?或许是指.NET的Generic? 
参见上面的例子。其实就是根据不同的生成选项 先 生成不同的代码 集结成库,方便快速进行链接。
当然其大小可能很大,但是比源码要快,同时在生成实际代码的时候只链入实际的部分。

6、完整的静态接口设计;
这年头,动态接口才是新闻。 
这个是和C++和JAVA的接口相比较的,实际上是在编译的时候进行多态,所以完全不需要继承和虚函数。
看看前面的那个例子max,仔细想想,你就会知道:继承是很多重用的根本。虚函数是一种实现机制,跟继承不可同日而语。编译时就可以确定某些Override的行为具体落实到那个代码片段上,运行时自然就可以直接调用。其实Java在这一点上已经做得非常好了,不过由于Java的优化是JIT的,你或许会觉得还是占用了运行时间,那么Eiffel的完全编译时搞定就能满足你了【完全不用修改现在的连接器】。 
我很不喜欢继承。也很不喜欢虚函数。按照上面的设计,其实完全是在编译期就静态绑定了。代码重用可以使用对象嵌入和委托。
7、原生支持并行;
如果是通用目的的并行,现在的Thread和Lock就完全支持了。而且也似乎只有它们才支持通用目的的并行。如果是特定场景下的并行,似乎不应该作为语言的特性存在吧。 
我觉得并行代码应该在底层支持映射到不同平台,同时定义一些原子级的变量、锁和操作
这需要一个比较庞大的运行时,或许叫虚拟机更恰当一点。 
编译的时候直接替换也是可以的。比如变量的原子操作,如果你直接编译为window+intel平台,那么 compiler会自动为你生成该变量的一个临界区对象,每次对变量的操作都会自动锁定和解锁;如果编译为某个直接支持内存锁定的平台,那么就直接映射。

up duan

unread,
Jul 9, 2010, 2:54:22 PM7/9/10
to pon...@googlegroups.com
加一个适配间接层。一致性不仅仅是美观,一致性也是控制复杂性的重要手段。一致性增加了重用性。

dachuan lin

unread,
Jul 9, 2010, 3:02:16 PM7/9/10
to pon...@googlegroups.com
说是那么说,但是如果太多层代码就很臃肿了。
另外,我这样设计主要是想解决掉例如#if #define 等预编译的情况下的大量问题(比如无法得到类型信息,出错时定位困难,代码丑陋等),直接加入“编译期代码”,既能搞定模板和concept,又能实现条件编译和自动代码生成,何乐而不为呢?

up duan

unread,
Jul 9, 2010, 9:49:15 PM7/9/10
to pon...@googlegroups.com
type traits不需要继承,不需要虚函数,不需要是自定义类,原始类型【比如int】也可以用。只是程序员手工把某些信息收集包装起来交给编译器,然后编译器就可以通过类型来进行静态分派了。
对于C++来说,traits的成员主要是typedef,ok?


宏是一个非常好的代码生成技术。当然,C的宏由于自身的一些限制导致不够理想,但是m4明显舒服的多,更别说scheme了。
你说的“类型库”就是“预编译的模板库”么?不太清楚你的标的是什么。不过业界早已把make技术用于代码生成了。 
类型库指的是你创建的库中所有的类型和函数的完整信息,比如类名,成员变量名称、类型,成员函数名称、参数、返回值、虚实等等。
同时,如果是模板类型的话,则会包含多重实践的代码;这个有点像delphi的单元+tlb
 
Java和.NET似乎都满足这个条件。除了你说的模板。
java等问题是,编译好的东西(比如库)包含 太多的信息,并会直接传递到最后的运行程序中。这造成了资源的浪费。我希望的是在生成lib的时候包含充分的信息,但最后link的时候尽可能的去除。
有时候运行时期才能确定很多事情,这也是动态语言表达能力强悍的原因。 
你没有理解我说的继承。你觉得max的参数是可比较的,是不是表明它们【参数】是继承自可比较的类型呢?不一定需要显式的说明,跟虚函数也没有什么关系。编译期【就是你说的预编译期】你必须把max得参数表达出来吧,你用什么类型表达?调用max的时候才有实际的类型不是么?而且很多时候运行时才知道具体的类型呢。委托不也是一个间接层么?而且一般还是手工完成的,不知道为什么你会不喜欢虚函数,编译器帮你搞定的间接层,而且不比你自己写性能低。 
7、原生支持并行;
如果是通用目的的并行,现在的Thread和Lock就完全支持了。而且也似乎只有它们才支持通用目的的并行。如果是特定场景下的并行,似乎不应该作为语言的特性存在吧。 
我觉得并行代码应该在底层支持映射到不同平台,同时定义一些原子级的变量、锁和操作
这需要一个比较庞大的运行时,或许叫虚拟机更恰当一点。 
编译的时候直接替换也是可以的。比如变量的原子操作,如果你直接编译为window+intel平台,那么 compiler会自动为你生成该变量的一个临界区对象,每次对变量的操作都会自动锁定和解锁;如果编译为某个直接支持内存锁定的平台,那么就直接映射。
还是那句话,对于变量的访问,一般只能在运行时才能确定,所以,你只能在运行时进行编译,是吗? 

dachuan lin

unread,
Jul 9, 2010, 10:28:25 PM7/9/10
to pon...@googlegroups.com
type traits不需要继承,不需要虚函数,不需要是自定义类,原始类型【比如int】也可以用。只是程序员手工把某些信息收集包装起来交给编译器,然后编译器就可以通过类型来进行静态分派了。
对于C++来说,traits的成员主要是typedef,ok?
traits好用就没人呼吁concept了。我其实就是想完善一下concept,把它彻底从“运行期代码”提升到“编译器代码”,同时完成绝大部分条件编译的功能而已;

不知道为什么你会不喜欢虚函数,编译器帮你搞定的间接层,而且不比你自己写性能低。
运行时多态的概念很好,但是我总觉得虚函数(以及虚函数表)的实现形式实在是很丑陋。最好的例子就是event(signal)-handler的对应。这个方面用map、hashtable等或维持一个额外的class function address table或许会更好?

Fuzhou Chen

unread,
Jul 9, 2010, 10:47:48 PM7/9/10
to pon...@googlegroups.com
> 这个方面用map、hashtable等或维持一个额外的class
> function address table或许会更好?

这这这……莫不是传说中的MFC?

> 运行时多态的概念很好,但是我总觉得虚函数(以及虚函数表)
> 的实现形式实在是很丑陋。

再说虚函数表的***实现形式***,真的那么重要?C++语法上并没有
暴露出虚函数表,我们用C++的时候基本上没什么机会关注虚函数
表是怎么实现的,除非——dachuan你和我一样,必须成天读反汇
编的C++代码。但我那是工作所迫,广大C++爱好者们估计没什么闲
心以看这个为乐吧。

2010/7/9 dachuan lin <lindach...@gmail.com>:

--
《采莲》·江南

为卿采莲兮涉水,为卿夺旗兮长战。为卿遥望兮辞宫阙,为卿白发兮缓缓歌。

另抄自蒜头的评论:http://www.douban.com/review/1573456/

  且祭一束紫琳秋,为一段落花流水的传说
  且饮一杯青花酒,为一场几多擦肩的错过
  且焚一卷旖旎念,为一腔抛付虚无的惜怜
  且歌一曲罢箜篌,为一刻良辰春宵的寂寞

dachuan lin

unread,
Jul 9, 2010, 10:56:03 PM7/9/10
to pon...@googlegroups.com
兄弟,同苦命啊,否则就不会抱怨了。。。

Fuzhou Chen

unread,
Jul 9, 2010, 11:11:43 PM7/9/10
to pon...@googlegroups.com
明白明白,理解万岁……

顺便也OT一下:其实基于COM的虚函数表还算好,跟GCC的
多继承表比起来,相对算容易理解的。

2010/7/9 dachuan lin <lindach...@gmail.com>:

莫华枫

unread,
Jul 9, 2010, 11:13:24 PM7/9/10
to pon...@googlegroups.com
个中问题颇为复杂。

2010/7/9 dachuan lin <lindach...@gmail.com>

严格来说,C和C++用来解决代码生成的技术,其实是走错了方向。
1、对于C来说,代码生成的方式主要是靠宏,其带来的问题就不用说了;
2、C++的创造者发现了宏的问题,其改善的方法,一个是发明了继承,不过这个其实只是擦擦边而已,真正接触到核心的还是模板(template)的引入。
 
继承并非bs发明。本质上也能算代码生成,但和宏之类的机制还是不一样的。模板最初是为了改善宏而来的,但殊途同归地成为了C++的GP核心。自从stl确立以后,模板就完全摆脱了“高级宏”的出身,完完全全成为正经的GP。

但是,这两者都是在歧路上越走越远。真正的解决之道,一方面如C#引入的,attribute,特性,

attribute是一个语法糖,传统上没有特别的重要性。但在concept中有一定的用处,它使得concept具备描述成员变量的能力。
 
另一方面,其实就应该光明正大的引入代码生成语言(不错,make configuration就是解决之道,可惜的是没有真正和C完全融合,并形成标准),以及预编译的模板库(或者类型库)。 
其实工程界早都已经自觉不自觉的引入了这些技术,比如windows下微软的类型库,以及广泛使用的make等技术,只是都不敢或者没想到把这些完全融合在一起。

代码生成在工程级别是一种非常有用的技术,我们现在的项目中就运用这种技术大幅简化开发工作。但始终是一种辅助技术。这个级别的代码生成只是静态的代码模板,没有灵活性可言。无法用于常规编程。
代码生成在语言中,就是元编程。模板天生具备元编程能力,但难于使用。D的static_if等也能算作元编程。我曾经构想过一种元编程型模,但经过反复思考和讨论,觉得这种模型过于技巧,诡异,可能会为编程带来不可预测的风险。
顺便提一下,fp语言天生就具备mp能力,能够运行时生成代码。它的诡异和晦涩难于言表,比如这里这里
 
在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
1、类似C的语法;
2、强类型语言,但是可以静态自动类型推断;

模板具备这个能力,但C++一半的复杂性也就在这上边。var和auto之类也具备这种能力。
更好的选择是利用conceot:
ConceptA x = func1();
这样,一方面减小了类型推断的难度,更进一步地为ide的智能提示提供了线索。
 
3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;

运行期代码生成几十年前就开始有尝试,但始终无法进入主流,并非没有原因。一则运行时代码生成实在难于控制,难于调试;二则运行时代码生成容易引发不可预见的bug。
真正堪用的运行时代码生成是fp语言,但对于多数程序员而言太难掌握。
 
4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
5、预编译模板库;

模板预编译存在技术难度,特别是在强调性能的情况下。
 
6、完整的静态接口设计;
7、原生支持并行;
8、原生支持GC;

对于C和C++,gc并非好的内存管理解决方案。C/C++是系统级语言,需要精确地控制每一个细节,包括内存管理,以其获得最大的性能。比如在函数局部使用堆内存,基于mempool的scope分配器可以获得与桟内存分配一样的效率。又比如,在单线程的情况下,可以只使用不带锁的分配器,减少锁的开销。还比如,为了减少系统调用,可以使用内存池。最重要的,系统开发也不希望时不时地来一下大规模的内存回收操作,可能会干扰系统的运行。原生的gc无法提供这样的自由度,对于应用层面地开发或许无所谓,但对于系统级的开发,性能都是隐藏在这样的细节中。而且,gc也可以在库的层面实现,
从资源管理的角度而言,gc并非最佳的手段。gc只能管理内存。为了解决其他资源的管理问题,不得不引入finally这类丑陋的特性。更好的资源管理手段是RAII。RAII非但能够管理内存、文件、socket等,还可以管理对象状态等广义上的资源。

C的方向并没有错,它定位在系统语言,尽可能接近底层,从而替代汇编。系统级语言要求精确直接地控制所有的要素。C++兼容了C,但却破坏了C的一些基本特性。有些是增加抽象特性的必须代价,比如操作符重载增加了语义的不确定性。另一些则是OOP带来的问题,比如对象布局和对象切割。前者是不得不接受的,而后者则是可以消除的。

这里所列的要求看起来更像是应用级语言的特性。要求系统级语言兼顾应用级语言的结果不会太好,C++就是前车之鉴。合理的做法是在不同的领域用不同的语言。但语言层次无需过多,一种系统级语言(C/C++)配合一些应用级语言(Python、js、php之类),形成高低搭配,发挥各自特长。重要的是不同语言间的交互。C++本身就缺乏统一的abi,更别提和其他语言的交互。这一点上C要容易得多。

莫华枫

unread,
Jul 9, 2010, 11:53:03 PM7/9/10
to pon...@googlegroups.com


2010/7/10 dachuan lin <lindach...@gmail.com>
你真的需要这样的特性吗?ML之类的语言(包括我的那个在内)都有更加优雅的解决方案,但是真的有人敢于在项目中用么?
 

没错,我知道这个和concept很相近,但是C++中的concept搞得很复杂,我不知道为什么,其实如果换个角度,把concept当作是编译器的指令代码,可以有特权来访问编译的
时候生成的类型完整信息的话,其实现会非常简单。

这和concept没关系,这是模板的特性,而且还是副产品。concept的定位在于GP,而这些特性属于MP。concept解决的是其它问题。即便concept有了这样的功能,也只能算是副作用,不应鼓励的东西。
我们来看看concept是如何解决的:
int max(NUMBER a, NUMBER b)
{
    return (a > b) ? a : b;
}
int max(Comparable a, Comparable b)
{
    return a.compare(b); // 或者: compare(a,b)
}
int max(any_type a, any_type b)
{
    throw ...;
}
复杂么?需要说明的是,这不是C++0x的语法,而是更加能够体现gp和concept优点的语法。
在concept方案中,如果需要增加一个类型判别,只需增加一个函数重载即可:
int max(LessThan a, LessThan b)
{
    return !(a < b);
}
而你的方案,需要修改max这个函数本身。设想一下,max是在你无法触及的库里定义的,你该怎么办?concept方案没有这个问题,无论在哪里,都可以重载一个函数。

 

   
宏是一个非常好的代码生成技术。当然,C的宏由于自身的一些限制导致不够理想,但是m4明显舒服的多,更别说scheme了。
你说的“类型库”就是“预编译的模板库”么?不太清楚你的标的是什么。不过业界早已把make技术用于代码生成了。 
类型库指的是你创建的库中所有的类型和函数的完整信息,比如类名,成员变量名称、类型,成员函数名称、参数、返回值、虚实等等。
同时,如果是模板类型的话,则会包含多重实践的代码;这个有点像delphi的单元+tlb

RTTI,runtime type info。主流语言大多都有,包括C++。只是C++标准在这方面没有很全面的定义。RTTI的主要作用是为那些没有正经MP能力的语言提供mp的能力。


 
在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
1、类似C的语法;
C的语法是如此的不清晰,还是不类似的好一些。 
简洁还是类C的好。当然新语言可以完全不考虑缺省类型自动转换等混淆的部分;

C语法的问题主要是non-lr,曾经有过C语法的lr改革方案,但终因饭已煮熟,无法实现。
如果引入完全的GP,抛弃OOP,可以完全放弃缺省类型自动转换,而不影响语言的灵活性。也就是像C一样灵活的Pascal。
 

 
2、强类型语言,但是可以静态自动类型推断;
好特性。好难。Haskell和OCaml以及Scala都有这些设施。 
3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;
至少现在的Java和.Net平台都提供了Compiler访问的API。而且编译器作为应用的一部分逻辑上需要虚拟机支撑,否则应用不能部署。而部署虚拟机本身就是一个问题。 
这个功能我觉得可以实现 嵌入式的脚本编译,脚本相当于是自己的语言。
为什么要虚拟机呢?比如在windows下生成的程序,自带windows下的compiler和linker,你可以在程序运行中,自动或由用户输入生成一段代码,然后调用附带的compiler编译到内存中,
然后返回函数指针,即可以进行调用。
4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
LLVM。 
是个好选择。是否可以用于代码生成?
5、预编译模板库;
……,不是很清楚这是什么意思,你是指C++的模板么?或许是指.NET的Generic? 
参见上面的例子。其实就是根据不同的生成选项 先 生成不同的代码 集结成库,方便快速进行链接。
当然其大小可能很大,但是比源码要快,同时在生成实际代码的时候只链入实际的部分。

C++如果不扫头源文件,编译速度可以很快。D也有模板,但没有编译速度问题。预编译模板麻烦大于好处。
 

6、完整的静态接口设计;
这年头,动态接口才是新闻。 
这个是和C++和JAVA的接口相比较的,实际上是在编译的时候进行多态,所以完全不需要继承和虚函数。

java等语言是把原本可以静态的东西动态作,因为它们没有静态的接口。这是缺点,不时优点。
 
7、原生支持并行;
如果是通用目的的并行,现在的Thread和Lock就完全支持了。而且也似乎只有它们才支持通用目的的并行。如果是特定场景下的并行,似乎不应该作为语言的特性存在吧。 
我觉得并行代码应该在底层支持映射到不同平台,同时定义一些原子级的变量、锁和操作

最好再加上coroutine,凑个圆满。
 

8、原生支持GC;
GC似乎仍然达不到通用目的。仍有适用场景。最好是可以通过声明允许或者禁止的。 
这个确实。可以禁止。
如果在系统级开发,一多半会被禁调。与其如此,还不如省掉这个麻烦特性。 

莫华枫

unread,
Jul 10, 2010, 12:01:09 AM7/10/10
to pon...@googlegroups.com


2010/7/10 dachuan lin <lindach...@gmail.com>



在 2010年7月9日 下午11:49,Milo Yip <mil...@gmail.com>写道:

C# 2.0 的 var 和 C++0x 的 auto 可滿足你對靜態自動類型推導的要求麼?
差不多。
不理解"完整的静态接口设计"
比如下面的代码:
[@gen: type TYPE is CLASS]
interface COMPARE {
    int  compare( TYPE &a1, TYPE &a2);
}
class COMPLEX
{
    int compare ( COMPLEX &a, COMPLEX &b){ ... }

}
[@gen: type TYPE]
int max(TYPE &a1, TYPE &a2)
{
    [@gen: if TYPE is NUMBER then ]
        return (a1>a2)? a1: a2;
    [@gen: elseif TYPE is CLASS && TYPE has @interface:COMPARE then]

        return a1.compare(a2);
    [@gen: else]
       throw std::exception::member_not_defined;
    [@gen: endif]
}
void fun1()
{
   COMPLEX a, b;
   return max(a, b);
}

可以看到,COMPLEX类完全不需要从COMPARE继承,也不需要任何的虚函数,在编译的时候, 自动会检查是否包含了interface的相关函数或成员,如果是就自动链入
其相对应的函数。要这么做,必须在编译的时候,编译器完全知道所有相关类型的信息。

接口和类型存在一个绑定。OOP利用继承,concept使所有concept_map。这里呢?用一种间接的,含糊的方式实现绑定,为什么不直接用以个关键字明确地表示呢?比如:
interface_bind Complex COMPARE;

莫华枫

unread,
Jul 10, 2010, 12:21:10 AM7/10/10
to pon...@googlegroups.com


2010/7/10 dachuan lin <lindach...@gmail.com>

type traits不需要继承,不需要虚函数,不需要是自定义类,原始类型【比如int】也可以用。只是程序员手工把某些信息收集包装起来交给编译器,然后编译器就可以通过类型来进行静态分派了。
对于C++来说,traits的成员主要是typedef,ok?
traits好用就没人呼吁concept了。我其实就是想完善一下concept,把它彻底从“运行期代码”提升到“编译器代码”,同时完成绝大部分条件编译的功能而已;

何来此言?现有的concept就是编译期代码,运行期的concept还只是一个概念而已。

dachuan lin

unread,
Jul 10, 2010, 1:55:21 AM7/10/10
to pon...@googlegroups.com
顺便也OT一下:其实基于COM的虚函数表还算好,跟GCC的
多继承表比起来,相对算容易理解的。
没错,ms不也臭屁的说:COM是更好的C++吗?呵呵

我在这里想比较深入的讨论一下关于“模板”和“条件编译”和“concept”等几个问题,基本上算是使用C、C++近十年的一点困惑和总结

1、关于模板,很显然这一开始就是为了解决“代码重用”的问题而来。问题是,C++中的模板和其要替代的“宏”一样,充满了非常大的缺陷,主要问题有几个:
【1】模板和宏一样,不了解参数的类型信息,为了区分使用了很多的匪夷所思的技巧,trait技术就是其中的佼佼者。问题是这对普通程序员带来巨大的学习和使用负担,同时,现有的编译器技术又不能很好的解决问题的定位问题,出错的信息冗长晦涩;
【2】模板并不能完全取代宏,它无法实现“条件编译”,从而无法实现编译时的配置。宏的“条件编译”问题见下面。由于这个原因,模板必须和宏共存;
【3】现有的大部分模板和宏一样,必须提供源码,导致在包含大的模板库的时候,有大量的编译时间耗费在不断的重复劳动中,而且也无法提供“知识产权”的保护。

综上,我个人认为模板技术是很不完备的,为了解决【1】而引入的concept,其问题也很大,放在下面阐述;为了解决【3】,必须提供预编译的模板库;

2、关于“条件编译”,首先我们要看到目前C、C++,不管是linux、windows几乎最后都回到makefile的使用上。当然有朋友会争论makefile并不是C或者C++,但是我们必须要看到这和实际的编程融合得越来越紧密,而且如果把眼光放开,就会发现其实所谓“通用编程,GP“,就是一种“条件编译”,就是“代码生成”,这三者实际上是一体的!
但是现有的makefile中的问题,是其采用了一套类似脚本的语言,其对象只是以文件为单位,粒度太大;以宏技术为主的条件编译,又不知道类型;GP知道类型了,又无法实现文件级别的融合。

3、关于“concept”,基本思想是很好的,但是主要问题是耦合度太高。我们知道编码应该追求的是松耦合,但是concept却强令类型和某concept强绑定。这为类的编写带来了不必要的限制。再以我上面的例子为例:

[@gen: type TYPE is CLASS]
interface COMPARE {
    int  compare( TYPE &a1, TYPE &a2);
}
class COMPLEX
{
    int compare ( COMPLEX &a, COMPLEX &b){ ... }

}

[@gen: type TYPE]
int max(TYPE &a1, TYPE &a2)
{
    [@gen: if TYPE is NUMBER then ]
        return (a1>a2)? a1: a2;
    [@gen: elseif TYPE is CLASS && TYPE has @interface:COMPARE then]

        return a1.compare(a2);
    [@gen: else]
       throw std::exception::member_not_defined;
    [@gen: endif]
}
int fun1()
{
   COMPLEX a, b;
   return max(a, b);  //---(1)
}
上面的代码中我们可以看到COMPLEX不需要从interface COMPARE中继承,它只需要带一个名称是compare的函数即可,(1)行中代码生成的时候,由编译器自动对interface compare和 COMPLEX类中的成员函数进行交叉匹配,如果合适就生成代码,否则指出不匹配错误。这样的代码完全可以自由胶合任意的第三方代码和原始类,达到低度耦合的目的。

 

莫华枫

unread,
Jul 10, 2010, 7:04:03 AM7/10/10
to pon...@googlegroups.com


2010/7/10 dachuan lin <lindach...@gmail.com>

顺便也OT一下:其实基于COM的虚函数表还算好,跟GCC的
多继承表比起来,相对算容易理解的。
没错,ms不也臭屁的说:COM是更好的C++吗?呵呵

我在这里想比较深入的讨论一下关于“模板”和“条件编译”和“concept”等几个问题,基本上算是使用C、C++近十年的一点困惑和总结

1、关于模板,很显然这一开始就是为了解决“代码重用”的问题而来。问题是,C++中的模板和其要替代的“宏”一样,充满了非常大的缺陷,主要问题有几个:
【1】模板和宏一样,不了解参数的类型信息,为了区分使用了很多的匪夷所思的技巧,trait技术就是其中的佼佼者。问题是这对普通程序员带来巨大的学习和使用负担,同时,现有的编译器技术又不能很好的解决问题的定位问题,出错的信息冗长晦涩;

模板当然不了解类型参数信息,编译器了解,模板是编译器处理的,自然会作出相应的解析。解决你所说的这些问题,就是concept的任务。
 
【2】模板并不能完全取代宏,它无法实现“条件编译”,从而无法实现编译时的配置。宏的“条件编译”问题见下面。由于这个原因,模板必须和宏共存;

模板具备元编程能力,自然能够实现条件编译,只是形式不同而已。如果熟悉fp,就不会觉得这种形式有多么奇怪。
 
【3】现有的大部分模板和宏一样,必须提供源码,导致在包含大的模板库的时候,有大量的编译时间耗费在不断的重复劳动中,而且也无法提供“知识产权”的保护。

条件编译不需要源代码?仔细想想,它们在实现上应该是等价的,不是吗?
 

综上,我个人认为模板技术是很不完备的,为了解决【1】而引入的concept,其问题也很大,放在下面阐述;为了解决【3】,必须提供预编译的模板库;

2、关于“条件编译”,首先我们要看到目前C、C++,不管是linux、windows几乎最后都回到makefile的使用上。当然有朋友会争论makefile并不是C或者C++,但是我们必须要看到这和实际的编程融合得越来越紧密,而且如果把眼光放开,就会发现其实所谓“通用编程,GP“,就是一种“条件编译”,就是“代码生成”,这三者实际上是一体的!

关于concept实现条件编译,请看上午我的回复中的案例。你也会看到,你的条件编译方案是侵入的,难于扩展,无法达到concept-based overloading的灵活性和扩展性。我们这个group在前年初曾经讨论过这些问题,我的blog也有一些分析和构想。
 
但是现有的makefile中的问题,是其采用了一套类似脚本的语言,其对象只是以文件为单位,粒度太大;以宏技术为主的条件编译,又不知道类型;GP知道类型了,又无法实现文件级别的融合。

3、关于“concept”,基本思想是很好的,但是主要问题是耦合度太高。我们知道编码应该追求的是松耦合,但是concept却强令类型和某concept强绑定。这为类的编写带来了不必要的限制。再以我上面的例子为例:

[@gen: type TYPE is CLASS]
interface COMPARE {
    int  compare( TYPE &a1, TYPE &a2);
}
class COMPLEX
{
    int compare ( COMPLEX &a, COMPLEX &b){ ... }

}

[@gen: type TYPE]
int max(TYPE &a1, TYPE &a2)
{
    [@gen: if TYPE is NUMBER then ]
        return (a1>a2)? a1: a2;
    [@gen: elseif TYPE is CLASS && TYPE has @interface:COMPARE then]

        return a1.compare(a2);
    [@gen: else]
       throw std::exception::member_not_defined;
    [@gen: endif]
}
int fun1()
{
   COMPLEX a, b;
   return max(a, b);  //---(1)
}
上面的代码中我们可以看到COMPLEX不需要从interface COMPARE中继承,它只需要带一个名称是compare的函数即可,(1)行中代码生成的时候,由编译器自动对interface compare和 COMPLEX类中的成员函数进行交叉匹配,如果合适就生成代码,否则指出不匹配错误。这样的代码完全可以自由胶合任意的第三方代码和原始类,达到低度耦合的目的。

concept耦合高?concept需要继承么?
“由编译器自动对interface compare和 COMPLEX类中的成员函数进行交叉匹配”,这就是耦合。耦合不可能避免,否则就无法将接口和类型关联。
或许我理解错了,从你的文字中,我觉得你认为一个类型只能同一个concept绑定。但实际上类型可以在任意时候,同任意多的concept绑定。
你说的自动匹配,在concept中同样存在。如果你仔细看过concept的proposal或者六君子的paper,或者未鹏同学的文章,就会发现,存在一种机制叫做auto concept mapping,使用关键字auto concept_map<>实现,一旦将一个concept定义成auto,编译器会自动绑定concept和类型,只要两者匹配。但是自动绑定也存在他的问题,一旦concept中的symbol和类型中的同名symbol具有不同的语义,则会引发问题(这个问题未鹏同学形象地使用插座和插头进行解释)。无论显式的绑定还是自动绑定,接口和类型始终是需要绑定的,耦合也是存在的,他们的耦合度是相同的。当然这种耦合远远小于OOP的继承。
从另一个角度讲,自动匹配的耦合反而强于显式绑定。自动匹配导致无论什么类型,无论什么语义,只要存在相同的symbol,就会绑定,一棍子打死一大片,一下子耦合一大片,难道比一个个地绑定来的更弱么?
你这里所提到的想法实际上并未超出concept的范畴,而且仅仅是concept的一小部分。concept给出的是更加优雅,更加接近本质的解决方案。C++0x的concept的复杂主要是因为语言既有的特性造成的。如果一门新的语言,完全可以用更加直观,更加简单的形式实现。我觉得你实际上并未充分地了解concept机制。如果能够深入地了解concept的本质,所需要的就是顺杆爬,即可获得更适合concept的形式。
关于这些,我们group曾经有过很精彩的讨论,我的blog上有一些文章专门做过整理和总结。

莫华枫

unread,
Jul 10, 2010, 7:11:26 AM7/10/10
to pon...@googlegroups.com
更正一下,auto concept mapping的形式是:auto concept<>{...}
另外说一句,正是因为标准委员会中的两派对于是否默认auto concept mapping存在分歧,导致concept提案被踢出C++0x。

2010/7/10 莫华枫 <longsh...@gmail.com>

dachuan lin

unread,
Jul 10, 2010, 7:48:24 AM7/10/10
to pon...@googlegroups.com
OK, 可能是很久没有关注concept的内容了,先了解一下

Fuzhou Chen

unread,
Jul 10, 2010, 4:29:42 PM7/10/10
to pon...@googlegroups.com
2010/7/9 dachuan lin <lindach...@gmail.com>:
> 【1】模板和宏一样,不了解参数的类型信息,为了区分使用了很多的
> 匪夷所思的技巧,trait技术就是其中的佼佼者。问题是这对普通程序员
> 带来巨大的学习和使用负担,同时,现有的编译器技术又不能很好的解
> 决问题的定位问题,出错的信息冗长晦涩;

模板确实不了解参数的类型信息,但我也一样可以说,OOP也不可以。
因为计算机永远不知道所谓的类型究竟是做什么用的。模板提供是类
型推导和分派的手段,正如引入了OOP使得程序员必须考虑类的继承
关系一样,引入了模板就使得程序员必须考虑类型推导,而这个推导的
具体手法就是通过traits。这是为了利用工具必须支付的学习成本,算
不上什么负担,只是我们得选择,看这个学习成本是不是能够被这个工
具带来的便利抵消掉。

而且即便是C++真的如老莫所言引入了concept,我认为这也不是问题的
结束。我相信真的引入了concept的那一天,我们肯定会开始面对新的麻
烦。虽然我们不能据此就从此拒绝引入concept,但这些麻烦绝对不能认
为是concept的缺陷。


> 【2】模板并不能完全取代宏,它无法实现“条件编译”,从而无法实


> 现编译时的配置。宏的“条件编译”问题见下面。由于这个原因,模板必须和宏共存;

这话就不对了。dachuan你前面说模板主要是为了解决代码重用,但条件编译
并不是代码重用的一部分,而是项目管理任务的一部分。所以模板其实没有必
要去解决。事实上现在更多的人都倾向于用编译管理工具(ant、scons、
msbuild)之类的来解决这个问题,而避免在代码中到处安插条件编译——还是
那句老话,这是可读性问题,不是可行性问题。而且根据UNIX的一般原则,我
个人也不喜欢用一个工具解决所有问题。

> 【3】现有的大部分模板和宏一样,必须提供源码,导致在包含大的模板库
> 的时候,有大量的编译时间耗费在不断的重复劳动中,而且也无法提供“知
> 识产权”的保护。

我认为这是实现问题,不是模板这个概念的问题。VC的预编译可以在很大程
度上减轻重复劳动的开销。只是可惜C++标准为了保证和#include兼容,没有
要求定义二进制的模板文件格式。如果能跟Obj-C那样提供一个#import,问题
估计就减轻很多。

至于知识产权保护么,我说一句不客气点的话:无论出于何种目的,任何玩弄
类型的代码,模板也罢,OOP的接口也罢,都不能改变它没有实际功能的本质。
Boost里的很多函数库也证明了,厂商是可以通过混用模板和二进制代码避免
暴露实现的。厂商保护的是真正完成实际任务的代码。如果连模板推导都要保护,
我宁可不再使用这个厂商的产品。

dachuan lin

unread,
Jul 10, 2010, 8:46:55 PM7/10/10
to pon...@googlegroups.com
呵呵,兄弟,可能是我没有说清楚。

在 2010年7月11日 上午4:29,Fuzhou Chen <cppo...@gmail.com>写道:
2010/7/9 dachuan lin <lindach...@gmail.com>:
> 【1】模板和宏一样,不了解参数的类型信息,为了区分使用了很多的
> 匪夷所思的技巧,trait技术就是其中的佼佼者。问题是这对普通程序员
> 带来巨大的学习和使用负担,同时,现有的编译器技术又不能很好的解
> 决问题的定位问题,出错的信息冗长晦涩;

模板确实不了解参数的类型信息,但我也一样可以说,OOP也不可以。
因为计算机永远不知道所谓的类型究竟是做什么用的。模板提供是类
型推导和分派的手段,正如引入了OOP使得程序员必须考虑类的继承
关系一样,引入了模板就使得程序员必须考虑类型推导,而这个推导的
具体手法就是通过traits。这是为了利用工具必须支付的学习成本,算
不上什么负担,只是我们得选择,看这个学习成本是不是能够被这个工
具带来的便利抵消掉。

而且即便是C++真的如老莫所言引入了concept,我认为这也不是问题的
结束。我相信真的引入了concept的那一天,我们肯定会开始面对新的麻
烦。虽然我们不能据此就从此拒绝引入concept,但这些麻烦绝对不能认
为是concept的缺陷。
其实C++缺少的就是静态类型信息获取吧,这个在代码生成的时候是很大的问题。concept当然可以解决大部分问题, 而且从逻辑上与template构成了完整:concept负责区分,template负责构建。但是C++标准的concept夭折,谁也不知道什么时候重新开始(似乎G++ concept也夭折了?),实在遗憾。



> 【2】模板并不能完全取代宏,它无法实现“条件编译”,从而无法实
> 现编译时的配置。宏的“条件编译”问题见下面。由于这个原因,模板必须和宏共存;

这话就不对了。dachuan你前面说模板主要是为了解决代码重用,但条件编译
并不是代码重用的一部分,而是项目管理任务的一部分。所以模板其实没有必
要去解决。事实上现在更多的人都倾向于用编译管理工具(ant、scons、
msbuild)之类的来解决这个问题,而避免在代码中到处安插条件编译——还是
那句老话,这是可读性问题,不是可行性问题。而且根据UNIX的一般原则,我
个人也不喜欢用一个工具解决所有问题。
代码中安插条件编译,这种粒度的区分我看不到有什么办法可以取代,呵呵,这个和黑盒白盒测试一样,在很多情况下是必须的。
不过确实静下心来考虑,确实不太符合UNIX的原则。

> 【3】现有的大部分模板和宏一样,必须提供源码,导致在包含大的模板库
> 的时候,有大量的编译时间耗费在不断的重复劳动中,而且也无法提供“知
> 识产权”的保护。

我认为这是实现问题,不是模板这个概念的问题。VC的预编译可以在很大程
度上减轻重复劳动的开销。只是可惜C++标准为了保证和#include兼容,没有
要求定义二进制的模板文件格式。如果能跟Obj-C那样提供一个#import,问题
估计就减轻很多。
兄弟,这个问题出现得太久,影响也太大。我感觉标准委员会是不想解决,比如extern template,但是似乎存在很大的问题。
我还是觉得,如果实现太难,那么可能暗示了这个概念有很大的缺陷。


至于知识产权保护么,我说一句不客气点的话:无论出于何种目的,任何玩弄
类型的代码,模板也罢,OOP的接口也罢,都不能改变它没有实际功能的本质。
Boost里的很多函数库也证明了,厂商是可以通过混用模板和二进制代码避免
暴露实现的。厂商保护的是真正完成实际任务的代码。如果连模板推导都要保护,
我宁可不再使用这个厂商的产品。
涉及到厂商政治话题就不好说了。
 

莫华枫

unread,
Jul 10, 2010, 9:18:08 PM7/10/10
to pon...@googlegroups.com


2010/7/11 dachuan lin <lindach...@gmail.com>

> 【3】现有的大部分模板和宏一样,必须提供源码,导致在包含大的模板库
> 的时候,有大量的编译时间耗费在不断的重复劳动中,而且也无法提供“知
> 识产权”的保护。

我认为这是实现问题,不是模板这个概念的问题。VC的预编译可以在很大程
度上减轻重复劳动的开销。只是可惜C++标准为了保证和#include兼容,没有
要求定义二进制的模板文件格式。如果能跟Obj-C那样提供一个#import,问题
估计就减轻很多。
兄弟,这个问题出现得太久,影响也太大。我感觉标准委员会是不想解决,比如extern template,但是似乎存在很大的问题。
我还是觉得,如果实现太难,那么可能暗示了这个概念有很大的缺陷。

有个model提案,好像是Abrams的,用于解决这个问题。如果顺利,可能进入C++0x之后的标准。至少他们的网站上这么说的。但是无论怎么着腾,non-lr语法终究是无法改变的。在bison中,non-lr语法是立方复杂度的。

dachuan lin

unread,
Jul 10, 2010, 10:40:28 PM7/10/10
to pon...@googlegroups.com
希望他们成功,呵呵。

est

unread,
Jul 11, 2010, 1:06:52 AM7/11/10
to pon...@googlegroups.com
http://code.google.com/p/gomingw

2010/7/7 Guanqun Lu <guanq...@gmail.com>:
> golang首先一点就不支持windows系统,这个就会对它的大规模流行产生负作用。
>
> 2010/7/7 Kula <kula...@gmail.com>:
>> 呵呵,20多年过去了,这个时候再来说c++处理大型项目的能力开始浮现,会不会太迟了。
>> 其实花在关注c++上的时间,我们完全可以拿来关注golang.假以时日,等golang成熟了.大批大批的软件又会用golang 重写。
>>
>>
>> 2010/7/7 Changsheng Jiang <jiang...@gmail.com>
>>>
>>> 赞同这句话.
>>>
>>> 在C编程时, 我最想用的 C++ 特性是模板式的代码生成, 这个可以减少重复代码量. 再一个是析构函数. 这个主要是在资源申请时指定资源释放,
>>> 并自动化.
>>>
>>> 模板在 C 里用宏比较丑陋. 我用过CPP之外的处理程序生成代码.
>>>
>>> 析构函数的自动化, 实在无法. 一个方法是将资源释放注册到一个栈式的地方, 栈弹出一层, 自动释放此层对应的所有资源.
>>>
>>> 反而觉得面向对象不是C++吸引C程序员的特性. 觉得面向接口更简单直接, 见过一些C++代码,  先声明接口 Interface, 再实现
>>> Impl, 实是受强类型的面向对象所累.
>>>
>>> 不知大家欣赏的C++ - C 的特性是什么?
>>>
>>>                                                      Changsheng Jiang
>>>
>>>
>>> 2010/7/7 up duan <fix...@gmail.com>
>>>>
>>>>
>>>> 2010/7/6 CXX16 <cplus...@gmail.com>
>>>>>
>>>>> 其实这个问题应该问为什么LLVM和CLANG要用C++。
>>>>>
>>>>
>>>> 作为一个没有压力的新项目,选择什么语言主要取决于实施者的感觉了。所以LLVM采用C++不太能说明什么问题。但是传统的C项目改为C++就很有说服力了。
>>>
>>
>>
>
>
>
> --
> Guanqun
>

Yongwei Wu

unread,
Jul 11, 2010, 5:39:01 AM7/11/10
to pon...@googlegroups.com
2010/7/11 dachuan lin <lindach...@gmail.com>:

> 在 2010年7月11日 上午4:29,Fuzhou Chen <cppo...@gmail.com>写道:
>> > 【3】现有的大部分模板和宏一样,必须提供源码,导致在包含大的模板库
>> > 的时候,有大量的编译时间耗费在不断的重复劳动中,而且也无法提供“知
>> > 识产权”的保护。
>>
>> 我认为这是实现问题,不是模板这个概念的问题。VC的预编译可以在很大程
>> 度上减轻重复劳动的开销。只是可惜C++标准为了保证和#include兼容,没有
>> 要求定义二进制的模板文件格式。如果能跟Obj-C那样提供一个#import,问题
>> 估计就减轻很多。

#import和#include没有本质区别吧。而且,Objective-C也不支持模板。

> 兄弟,这个问题出现得太久,影响也太大。我感觉标准委员会是不想解决,比
> 如extern template,但是似乎存在很大的问题。我还是觉得,如果实现太
> 难,那么可能暗示了这个概念有很大的缺陷。

是我理解错了,还是大家没听说过export这个关键字?不需要源代码的模板概念
早就被提出来了,但只有Comeau一家实现了。

http://www.comeaucomputing.com/4.0/docs/userman/export.html

由于实现非常复杂,困难度很高,目前没有其他编译器支持,所以实际上没人使
用。这似乎也是唯一一次C++标准委员会把一个还没经过验证的特性加到标准里
(C++-98)。确实,这个概念“听起来很美”。

我听说export将在C++0x中被deprecate。

--
Wu Yongwei
URL: http://wyw.dcweb.cn/

up duan

unread,
Jul 11, 2010, 5:43:44 AM7/11/10
to pon...@googlegroups.com
> 兄弟,这个问题出现得太久,影响也太大。我感觉标准委员会是不想解决,比
> 如extern template,但是似乎存在很大的问题。我还是觉得,如果实现太
> 难,那么可能暗示了这个概念有很大的缺陷。

是我理解错了,还是大家没听说过export这个关键字?不需要源代码的模板概念
早就被提出来了,但只有Comeau一家实现了。

http://www.comeaucomputing.com/4.0/docs/userman/export.html

由于实现非常复杂,困难度很高,目前没有其他编译器支持,所以实际上没人使
用。这似乎也是唯一一次C++标准委员会把一个还没经过验证的特性加到标准里
(C++-98)。确实,这个概念“听起来很美”。

我听说export将在C++0x中被deprecate。

不是废弃,是删除。这也证明了这个特性的不切实际。 

dachuan lin

unread,
Jul 11, 2010, 5:43:59 AM7/11/10
to pon...@googlegroups.com
老兄,我上面说错了,确实应该是export。
当初为什么要加入,就是因为实在太重要了。
这个特性废弃太可惜了。

Fuzhou Chen

unread,
Jul 11, 2010, 2:38:43 PM7/11/10
to pon...@googlegroups.com
我个人的猜想是export的实现需要全局编译的支持,而这个功能
跟C传统的编译模型是冲突的,所以大部分编译器厂商在实现的
时候应该是遭遇了实际的困难而不愿意支持这个特性。有时候我
也想,如果是Effiel那样支持全局分析的编译器,或许这个问题就
好办很多。

至于Yongwei说的“#import和#include没有区别”,我想我没说明白。
我的意思是如果当初C++的设计过程中能够不那么严格地遵守“和C
共享连接器”这个要求,就可能在编译层面大胆引入一些功能使全
局编译变得可行,那么这个export关键字也许就没有这么难实现。
可惜,历史是不能如果的。


厂商问题么,之前我激动了些,现在想想,俺们说这个确实不合
适,还是搁置吧,别在意,呵呵。

2010/7/11 dachuan lin <lindach...@gmail.com>:

--

Kula

unread,
Jul 11, 2010, 9:25:56 PM7/11/10
to pon...@googlegroups.com
Effiel为什么没有流行开呢?

2010/7/12 Fuzhou Chen <cppo...@gmail.com>

Fuzhou Chen

unread,
Jul 11, 2010, 11:12:47 PM7/11/10
to pon...@googlegroups.com
这个原因复杂多了,我也不是Effiel专家,只是短期接触过一点而已。
我个人的口味是,过于原教旨主义的主张我都不太喜欢。

2010/7/11 Kula <kula...@gmail.com>:

Jack.Chu

unread,
Jul 12, 2010, 1:13:25 AM7/12/10
to TopLanguage
你是想说Java吧?!

On Jul 9, 9:58 pm, dachuan lin <lindachuan2...@gmail.com> wrote:
> 严格来说,C和C++用来解决代码生成的技术,其实是走错了方向。
> 1、对于C来说,代码生成的方式主要是靠宏,其带来的问题就不用说了;
> 2、C++的创造者发现了宏的问题,其改善的方法,一个是发明了继承,不过这个其实只是擦擦边而已,真正接触到核心的还是模板(template)的引入。
> 但是,这两者都是在歧路上越走越远。真正的解决之道,一方面如C#引入的,attribute,特性,另一方面,其实就应该光明正大的引入代码生成语言(不错,make
> configuration就是解决之道,可惜的是没有真正和C完全融合,并形成标准),以及预编译的模板库(或者类型库)。
> 其实工程界早都已经自觉不自觉的引入了这些技术,比如windows下微软的类型库,以及广泛使用的make等技术,只是都不敢或者没想到把这些完全融合在一起。

> 在我的理想中,真的希望能够有一种语言,可以完全实现以下的功能:
> 1、类似C的语法;

> 2、强类型语言,但是可以静态自动类型推断;
> 3、代码分两部分:生成阶段语言和运行阶段语言,编译器可以作为库链入代码中;


> 4、在生成库的时候,带上最完整的类型信息,最后link为exe时可以尽可能优化;
> 5、预编译模板库;

> 6、完整的静态接口设计;
> 7、原生支持并行;
> 8、原生支持GC;
>

> 在 2010年7月9日 下午2:57,莫华枫 <longshank...@gmail.com>写道:
>
> > C++优点和缺点一样明显。
> > 严格地讲,C++的优点也不是什么特别伟大的东西,只是顺应了一些本质规律,给予更多的选择,而不是拘泥于某种单一的范式。
>
> > C++的缺点则来源广泛,一部分来自C,比如non-lr的语法,隐式的类型转换,资源管理困难,陈旧的编译模型等等。有些来自于过于机巧的设计,比如默认的隐式类型转换构造和操作符,操作符","的重载等等。有些来自于委员会的扯皮,比如ABI问题,逻辑操作的执行次序问题等等。以及添油式的设计,比如GP作为后加入的特性无法同早期OOP特性完美地协调。
>
> > BS创建C++的时候试图利用OOP消除C存在的问题。但是全面兼容C减少了推广的困难,却导致了语法上的混乱。毕竟C是一门独立完备的语言,设计时也没有考虑未来的特性扩展,使得原本non-lr的语法更加复杂,编译时间暴涨,而编译器的开发更加困难。
>
> > OOP的引入当时看起来是对C语言很好的扩充,但现在看来OOP反而引发了很多问题。问题的根源在于OOP并非完善的抽象体系。相反,OOP只能算作一个半熟的解决方案。在C++领域中,OOP有广义和狭义之分。广义上,OOP包括OB、重载和动多态,甚至有人将GP的一些特性算作OOP范畴。狭义上,OOP单指动多态。真正有问题的是狭义OOP,即动多态。
>
> > OB是C++最重要的特性,这是一个完全正面的特性。封装是所有抽象的基础。在此基础上增设的RAII(即自动对象)是C++相对于C最好的补充。RAII允许进入和离开一个scope时执行特定的操作,这是一种极好的资源和状态管理的手段。
> > 继承是依附于封装的特性,但继承存在两重性。作为代码重用机制,很大地提高了开发效率。但另一方面,继承却不恰当地成为OOP的动多态基础。
>
> > OOP(以下OOP仅指动多态)是一种有缺陷的抽象机制,是基于类型和继承的多态。但其中存在根本性的问题。举个例子,计算金额,我们会说把单价*数量。用程序员的语言,就是:一个浮点数*一个整数。这是抽象的说法,说这句话的时候我们没有明确指定单价是什么样的浮点数,是single还是double,什么样的整数,是4字节还是8字节。这是很自然的逻辑。但是在OOP中无法这样描述。我们只能说:一个从float类型上继承的数*一个从integer类型上继承的数。因为在OOP中是通过一种类型来描述一组类型的,两者的联系就是继承。这中间的问题在于,继承是一种很强的耦合关系,依赖于这种关系的抽象体系是侵入的。由于继承关系的存在,接口成为了类型的一部分,一个类型所支持的接口,必须在定义时决定,以后无法扩展。即便一个类型同一个接口完全一致,只要没有继承关系,就不是一家人。形象地说,老虎A,无论多么像老虎B,只要不是老虎B的崽,它就不是老虎。这显然是荒谬的。问题就是我们用一只老虎来指代老虎这个物种。OOP却是这么做的,用一个类型来抽象一组类型。
> > 更糟糕的是,C++引入OOP还带来了意想不到的问题。首当其冲的是对象切割问题:
> > class A
> > {...};
>
> > class B : public A
> > {...};
>
> > B arrayB[10];
> > A pa = arrayB;
> > pa[3]->... //你访问的是什么?
>
> > 很显然,最后那行代码是一个错误的访问。pa[3]是按A计算的偏移,而pa真正指向的是B的数组,两者的偏移可能是不一样的。问题的根本是为了实现动多态,继承类指针可以隐式地转换成基类的指针。而C的数组和指针又是等价的。
> > 从这一点上说,C是不适合引入OOP机制的。C太底层,而OOP又不完备。
>

> > 但另一种抽象机制----GP的引入却是非常恰当的。模板,无论是类模板还是函数模板,提供了一套完全独立于类型的抽象系统,很好地回避了"老虎不是老虎"的问题。而在C++0x中引入未果的concept则是GP机制的一个重要的完善。


> > OOP和GP两种机制分别应对动多态和静多态。看似相互补充,各有分工,但实际上凭空增加了语言的复杂性,难于融合。OOP本身的缺陷加剧了问题的混乱。一种语言只应当有一种抽象体系。对C而言,如果要增加抽象体系,GP比OOP更合适。GP目前只有静多态。但是随着concept的完善,runtime
> > concept也浮出水面,进而促使GP具备动态的抽象能力。这样程序员就不会迷失在两套不同的抽象体系中。
> > GP还有能力消除C语言的某些缺陷。比如,C不能算真正意义上的强类型,因为存在隐式类型转换,容易造成编码的错误。这一点在当年C vs
> > Pascal的论战中是重要的把柄。但如果没有这些转换,又无法获得足够的灵活性。C++对C所作的扩展并未解决这些问题,反而增加了其他更多的问题,特别是依赖于继承的隐式类型转换。而GP的抽象体系却可以在强化C的类型系统的情况下,提供足够的灵活性。这一点在Ada上就有所体现。Ada是先有GP(Ada83),后有OOP(Ada95)。如果Ada能够向runtime
> > GP,而非时髦的OOP发展,或许更有意义。
>
> > --
> > 反者道之动,弱者道之用

> > longshank...@gmail.com
> >http://blog.csdn.net/longshanks/
> > wave开通

Yongwei Wu

unread,
Jul 12, 2010, 9:17:57 AM7/12/10
to pon...@googlegroups.com
2010/7/11 up duan <fix...@gmail.com>:

现在再搜了一下,翻墙看到了Sutter的三月会议总结:

For context, the only reason we’re even considering this [deprecate,
remove, or leave] is because Edison Design Group (EDG), the only
company to ever implement export, is recommending export be removed or
deprecated. Recall that back in the 1990s the committee originally
voted the feature in over EDG’s objections in the first place, then in
the late 1990s and early 2000s EDG graciously and gallantly went on to
invest enormous effort to implement the feature in order to conform to
the standard, and so the committee was loath to punish them again by
now removing the feature on them. However, given the passage of time,
EDG reports that their experience in the field has been that nearly no
one actually uses the feature, and that it would be right (and okay
with EDG) to deprecate or remove it.

At our previous meeting, the general sentiment was in favor of
deprecation only. However, at this meeting EDG reported that they
would prefer the feature to be removed rather than just deprecated,
because a deprecated feature is still part of the standard and
required for conformance. By removing it from C++0x, it removes the
maintenance burden of being forced to support export indefinitely to
maintain full standards conformance (though of course EDG will
continue to support it as an extension in their compiler front end for
however long seems right based on their own customers’ demand).

The committee agreed, and today voted to remove export entirely from
C++0x. The “export” keyword is still reserved for future use, but has
no defined meaning in the C++0x standard.

上次是考虑要废弃的。而唯一实现了export的公司(Comeau使用的就是EDG的技
术)都出来说赞成删除,于是export就被干掉了。

dachuan lin

unread,
Jul 13, 2010, 12:34:57 AM7/13/10
to pon...@googlegroups.com
太悲伤了。
Reply all
Reply to author
Forward
0 new messages