关于项目中大量使用静态类和静态方法的好处与缺点

2,129 views
Skip to first unread message

cdredfox

unread,
Sep 6, 2009, 4:06:26 AM9/6/09
to pon...@googlegroups.com, pyth...@googlegroups.com
如果在一个项目中大量使用静态类或者静态方法(无所谓什么 语言),到底有哪些不好的地方和哪些好的地方呢?欢迎大家列举出来!
我先扔块砖头出来:
不好的地方:
1,对面向对象语言中,可能破坏了面向对象的结构,因为使用静态类或者静态方法,就失去了extend的特征了。
2,对于系统架构来说,可能感觉起来不是很合理。
3,在高并发的情况中,容易导致数据出错(此项未验证,只是推测。因为是全局的。)
好的地方:
1,感觉使用起来方便一些
2,不用重复的new一大堆对象,和销毁。可能在性能上略有提升。(but:但是会占据一定的内存空间)

欢迎大家指正。热情讨论

Jeffrey Zhao

unread,
Sep 6, 2009, 4:28:27 AM9/6/09
to pon...@googlegroups.com
似乎“感觉”成分比较高,一些性能阿,内存什么的,应该通过数据或理论说话,而不是靠感觉的。

比如,你说的“不好3”没有什么道理,还有“好2”……

静态类和静态方法,如果只是一些辅助函数,或者说,没有side effect的函数,问题是不大的,要有问题最多就是设计上是否妥当了。

我是不倾向于使用静态方法,因为难以扩展,难以测试(如无法mock)。

如果真有全局函数的要求,我宁愿使用Singleton,或共享数据源的方式(也就是数据源是全局的,但是操作类是instance的)。

Blog: http://www.cnblogs.com/JeffreyZhao/
Twitter: http://twitter.com/jeffz_cn

--------------------------------------------------
From: "cdredfox" <cdre...@gmail.com>
Sent: Sunday, September 06, 2009 4:06 PM
To: <pon...@googlegroups.com>; <pyth...@googlegroups.com>
Subject: [TL] 关于项目中大量使用静态类和静态方法的好处与缺点

Fei Yan

unread,
Sep 6, 2009, 5:14:08 AM9/6/09
to pon...@googlegroups.com
这个跟语言的关系应该很大,单纯抽象的讨论,可能没有一致的答案。

譬如在c++中,

1> 有时候static可能比non-static更优
    如果某个成员函数可以用某个类的现有public函数来实现,那么还是将其和类本身剥离开做成一个free function为好(当然最好有namespace);实际的效果就和其它纯OO语言的static方法没两样。
具体缘由,参看: http://www.ddj.com/cpp/184401197, How non-member function improve encapsulation,by Scott Meyers

2> ABI接口上的优势
另外一个有用的场合,就是C/C++混合接口的时候, 静态类或者静态方法,做一个接口给C用是比类成员函数要方便的多。
甚至由于c++ ABI缺失的原因,某些对ABI有很高要求的设计里边暴露的接口可能全部是C-style,那里唯一允许存在的大概只有free function和static function。

3> 架构问题
在C++系统里边,个人认为静态方法或者静态类很多,不一定和架构有什么关系,也未必有什么不合理;设计得当,哪一种方式我都会感觉很正常。

由于C/C++是要求programmer拥有自己管理资源的能力,所以导致数据出错的情形,大概更多和数据设计有关系。把接口设计的易于用对、难以用错,那么即使static也没关系;反之你拥有一个状态、invariants不明晰的类,即使没有一个static,也可能很糟糕。

-------------------------------------------------------------------------------
在Python中,static本身是不存在的,只能理解所谓的static就是module里边的function
1> function本身是first-class type, 所以function和class的界限本身不是那么明确的,你甚至可以动态的修改function/class的__dict__(new style class)
2> 高并发的情况,最好还是核心部分用C写的效果要好得多,出错不见得
3> 两者用起来没太大差别



2009/9/6 cdredfox <cdre...@gmail.com>

Shuo Chen

unread,
Sep 6, 2009, 5:41:38 AM9/6/09
to TopLanguage
太笼统了,能不能拿点具体的例子来说?

比如 Java 的 Thread class,
static method 有 sleep, currentThread
instance methods 有 start, join。
这不都挺好的吗?

针对你说的几点:
1. C++ 有全局函数,用 std::sort (相当于 static class std 的 static function sort)
就"破坏了面向对象的结构"了吗?
2. 恰恰相反,函数才是最佳复用单元,输入输出参数一目了然,没有别的瓜葛,扔到哪儿都能用。
3. 用 thread local 好了。

Shuo Chen

unread,
Sep 6, 2009, 5:56:11 AM9/6/09
to TopLanguage
C++的全局函数也可以mock,链接到不同的库就行。比如众多的 malloc debug library,用来mock全局函数
malloc。
有的都甚至不需要重新编译,设置一个 LD_PRELOAD 环境变量就行(Linux下)。

On Sep 6, 4:28 pm, "Jeffrey Zhao" <je...@live.com> wrote:
> 似乎"感觉"成分比较高,一些性能阿,内存什么的,应该通过数据或理论说话,而不是靠感觉的。
>

> 比如,你说的"不好3"没有什么道理,还有"好2"......


>
> 静态类和静态方法,如果只是一些辅助函数,或者说,没有side effect的函数,问题是不大的,要有问题最多就是设计上是否妥当了。
>
> 我是不倾向于使用静态方法,因为难以扩展,难以测试(如无法mock)。
>
> 如果真有全局函数的要求,我宁愿使用Singleton,或共享数据源的方式(也就是数据源是全局的,但是操作类是instance的)。
>
> Blog:http://www.cnblogs.com/JeffreyZhao/
> Twitter:http://twitter.com/jeffz_cn
>
> --------------------------------------------------

> From: "cdredfox" <cdred...@gmail.com>

Jeffrey Zhao

unread,
Sep 6, 2009, 6:05:43 AM9/6/09
to pon...@googlegroups.com
这是被我称为Compile for testability的做法,我比较信仰Design for
Testability。

因为后者更注重的是设计,例如把变化的和不变的隔离开来,例如剥离与malloc等系统函数的依赖。

所以就算使用.NET我也不太喜欢用typed mock这样过于前大的mock框架(它基于clr
profiler,几乎能改变一切方法的行为)。

因为太强的东西容易破坏设计,而不是让开发人员把注意力放在设计上面。

--------------------------------------------------
From: "Shuo Chen" <gian...@gmail.com>
Sent: Sunday, September 06, 2009 5:56 PM
To: "TopLanguage" <pon...@googlegroups.com>
Subject: [TL] Re: 关于项目中大量使用静态类和静态方法的好处与缺点

Fei Yan

unread,
Sep 6, 2009, 6:07:40 AM9/6/09
to pon...@googlegroups.com
纯OO的世界里,静态的东西是常常被排挤的;但是c++本身不是所有都要OO(OO只是4个不同世界里的一个),C里边好的东西也是直接拿来就用的;譬如这个例子里的libumem等;

其实LD_PRELOAD更多来源于Unix的设计哲学和C,c里边可没有成员函数,虽然你可以用复杂的函数指针表来搞一套

在纯OO的世界里,似乎一切东西都要考虑可扩展,譬如Java里边默认的virtual,我认为这似乎是个放任过度OO的特性
当然OO本身的普适性很早就收到了质疑,no silver bullet, even with OO


2009/9/6 Shuo Chen <gian...@gmail.com>

Jeffrey Zhao

unread,
Sep 6, 2009, 6:11:05 AM9/6/09
to pon...@googlegroups.com
其实OO的普适性不应该受到质疑……因为肯定不普适啊,既然no silver bullet。
 
我比较反对virtual by defaut和virtually everything的做法,我比较相信“开放与否,如何开放”是我来决定的,而不是语言帮我决定的。
 
当然也有人认为,和我类似的观点其实是基于一个错误的假设“我们知道用户会怎么使用我们的框架”。
 
这个东西到现在还没定论的。

From: Fei Yan
Sent: Sunday, September 06, 2009 6:07 PM
Subject: [TL] Re: 关于项目中大量使用静态类和静态方法的好处与缺点

Fei Yan

unread,
Sep 6, 2009, 6:30:26 AM9/6/09
to pon...@googlegroups.com
这个Thread本身,我觉得让LZ感到静态的东西都是别扭的原因,大概主要是来自于纯OO世界里,对static和non-OO方式的默认排斥

当一个designer对某一种方式感到特别别扭的时候,就会在设计的时候,潜意识里边抵制它,从而也很可能失去了发现elegance的机会

我个人的理解,Java这类纯粹的OO语言(甚至平台)里边,除了用OO方式来编程,其它的方式都不是best practice,都是权宜之计的样子

但是真正的应用环境,其复杂性是千差万别的,刚好某种方式在特定的context下是最优,而你又按照教条恰恰认为其“不自然”,那么后果就可想而知

BTW, OO比较受到公认强大的领域,大致集中于3D、GUI 和 Multimedia;其他的领域,确实争议颇多,即使是通用基础类库这样的东西,也都深深绑定于不同的语言,有纯OO实现的,也有非OO

2009/9/6 Jeffrey Zhao <je...@live.com>

raymond

unread,
Sep 6, 2009, 11:56:13 AM9/6/09
to TopLanguage
用或者不用看项目的具体需求,前端时间看到一个帖子,叫做从设计看设计师的性格,其实,解决问题的办法有很多,而且似乎并不是一种比另外一种好多少多
少,这个就只能看具体的设计者了。
就实际情况来说,我很少见到项目中大量使用静态类,一般来说,就是资源类,测试框架类等的使用静态类多一些。
我的感觉是,静态类更注重过程,而非静态类注重数据,所以,在一些注重过程的地方,比如字符串处理,参数检查等这些都可以过程静态,而对于数据敏感的,
比如某条记录会被。。。。处理一般,使用静态类就不太好了,因为静态类不适合修改状态。
而一些函数式编程语言中,上面的这段话就不对了,我觉得函数式语言的重点就在处理过程,所以,感觉就好象大量使用静态类的C++一样,只是感觉。

久远

unread,
Sep 6, 2009, 12:09:27 PM9/6/09
to TopLanguage
我赞同函数是最佳复用单元的说法。很多时候只是需要完成一个操作实现一个功能,谁来实现怎样实现并不重要。所以在适当的场合下用普通函数或者静态方法没
有什么不好的。
至于对面向对象的结构的破坏,我觉得,如果为了面向对象而面向对话的话,未免有些教条了。系统架构方面,好不好也没有绝对的定论,应该还是根据具体情况
来看的。合适的才是最好的。
然后在高并发的场合下,静态数据的确需要很好的保护——但是实际上即使不是静态数据,也需要很好的保护,所以静态并不显著的构成缺点。

我倒是觉得,静态对象的一个缺点是增加了可执行文件的大小,不过在现有的存储和网络条件下,也不见得是太大的缺点啦。

> > 欢迎大家指正。热情讨论- 隐藏被引用文字 -
>
> - 显示引用的文字 -

Jeffrey Zhao

unread,
Sep 6, 2009, 12:23:24 PM9/6/09
to pon...@googlegroups.com
为什么说静态对象会增加可执行文件的大小啊?

--------------------------------------------------
From: "久远" <d3dc...@gmail.com>
Sent: Monday, September 07, 2009 12:09 AM
To: "TopLanguage" <pon...@googlegroups.com>
Subject: [TL] Re: 关于项目中大量使用静态类和静态方法的好处与缺点

> 我赞同函数是最佳复用单元的说法。很多时候只是需要完成一个操作实现一个功能,谁来实现怎样实现并不重要。所以在适当的场合下用普通函数或者静态方法没

久远

unread,
Sep 6, 2009, 9:31:43 PM9/6/09
to TopLanguage
静态对象是保存在可执行文件的数据段里面的,所以会增加可执行文件的大小。普通的对象是运行时在栈或者堆上面动态分配的空间。

On 9月7日, 上午12时23分, "Jeffrey Zhao" <je...@live.com> wrote:
> 为什么说静态对象会增加可执行文件的大小啊?
>
> Blog:http://www.cnblogs.com/JeffreyZhao/
> Twitter:http://twitter.com/jeffz_cn
>
> --------------------------------------------------

> From: "久远" <d3dco...@gmail.com>

> >> - 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -

久远

unread,
Sep 6, 2009, 9:41:05 PM9/6/09
to TopLanguage
刚刚测试了一下,如下的程序:
#include "stdafx.h"
#include <iostream>
using namespace std;

static int data[1024*1024]={1,2,3,4,5,6,7,8,9,0,11,12,24,};

int main( int argc,char** argv )
{
system("pause");
return 0;
}
编译后的大小是4947kb

修改成下面的代码以后,只有28k。猜测应该是系统进行了优化,延迟加载什么的。环境是VS2008.
#include "stdafx.h"
#include <iostream>
using namespace std;

static int data[1024*1024]; //去掉了初始化

int main( int argc,char** argv )
{
system("pause");
return 0;
}

Jeff Chen

unread,
Sep 6, 2009, 9:43:23 PM9/6/09
to pon...@googlegroups.com
相差这么大,很好的试验

2009/9/7 久远 <d3dc...@gmail.com>



--
My Blog:http://jeffchen.cn

Jeffrey Zhao

unread,
Sep 6, 2009, 9:51:00 PM9/6/09
to pon...@googlegroups.com
我觉得是因为你省下了{1,2,3,4,5...}所以体积小了吧,和静态有关系吗?

你把对data的赋值放在main里面会是什么样?

Jeffrey Zhao
Blog: http://www.cnblogs.com/JeffreyZhao
Twitter: http://twitter.com/jeffz_cn

--------------------------------------------------
From: "久远" <d3dc...@gmail.com>
Sent: Monday, September 07, 2009 9:41 AM


To: "TopLanguage" <pon...@googlegroups.com>
Subject: [TL] Re: 关于项目中大量使用静态类和静态方法的好处与缺点

> 刚刚测试了一下,如下的程序:

hu

unread,
Sep 6, 2009, 9:53:10 PM9/6/09
to TopLanguage
到处都是静态的估计是没设计好,要不不至于。

Shuo Chen

unread,
Sep 6, 2009, 11:08:06 PM9/6/09
to TopLanguage
初值全为0的静态数据放在BSS段,不占可执行文件的空间。
初值不为零的静态数据放在DATA段,增加可执行文件的大小。
在Linux下用可用objdump看。
具体可参考《程序员的自我修养——链接、装载与库》

Hongzhang Liu

unread,
Sep 6, 2009, 11:31:05 PM9/6/09
to pon...@googlegroups.com
从.data移动到了.bss

2009/9/7 久远 <d3dc...@gmail.com>:

Fei Yan

unread,
Sep 7, 2009, 12:40:42 AM9/7/09
to pon...@googlegroups.com
确认你的编译选项是否一致
同样的程序(将stdafx.h换为stdlib.h),我用gcc编译的大小完全一样,都是 7.7K

readelf的program sections也完全一样的,并且其数据都不在bss静态分配,而是加了WA标志,表明是动态Alloc,大小28。

=====================================================================
cat TestStatic1.cpp

#include <iostream>
#include <stdlib.h>

using namespace std;

static int data[1024*1024];


int main( int argc,char**  argv )
{
           system("pause");
                  return 0;
}

readelf --sections TestStatic1 | grep bss 
  [21] .bss              NOBITS          00020ac0 000abc 000028 00  WA  0   0  8

-------------------------------------------------
cat TestStatic.cpp
#include <iostream>
#include <stdlib.h>


using namespace std;

static int data[1024*1024]={1,2,3,4,5,6,7,8,9,0,11,12,24,};

int main( int argc,char**  argv )
{
           system("pause");
                  return 0;
}

readelf --sections TestStatic | grep bss
  [21] .bss              NOBITS          00020ac0 000abc 000028 00  WA  0   0  8


2009/9/7 久远 <d3dc...@gmail.com>

久远

unread,
Sep 7, 2009, 1:48:58 AM9/7/09
to TopLanguage
编译环境完全一致,其实就是两行代码分别注释一下再编译。
难道是不同的编译器有不同的处理方式?

> 2009/9/7 久远 <d3dco...@gmail.com>


>
>
>
> > 刚刚测试了一下,如下的程序:
> > #include "stdafx.h"
> > #include <iostream>
> > using namespace std;
>
> > static int data[1024*1024]={1,2,3,4,5,6,7,8,9,0,11,12,24,};
>
> > int main( int argc,char** argv )
> > {
> > system("pause");
> > return 0;
> > }
> > 编译后的大小是4947kb
>
> > 修改成下面的代码以后,只有28k。猜测应该是系统进行了优化,延迟加载什么的。环境是VS2008.
> > #include "stdafx.h"
> > #include <iostream>
> > using namespace std;
>
> > static int data[1024*1024]; //去掉了初始化
>
> > int main( int argc,char** argv )
> > {
> > system("pause");
> > return 0;

Thronds

unread,
Sep 7, 2009, 7:23:32 AM9/7/09
to TopLanguage
在C中,从谭浩强书中知道了static定义的内部函数的优点,限制了函数的作用域。在自己开发的模块中,
如果确认函数不需要被别人的模块调用,那么定义成内部函数,将函数局部化,可以避免冲突。体现了模块化的特性。
但,需要注意的是,static函数不生成函数符号表,在运行调试等方面会有一定的缺陷。


On 9月6日, 下午4时06分, cdredfox <cdred...@gmail.com> wrote:

sagasw

unread,
Sep 7, 2009, 7:37:35 AM9/7/09
to pon...@googlegroups.com
static函数不生成函数符号表,在运行调试等方面会有一定的缺陷。

这一块不是很明白,能否解释一下?





2009/9/7 Thronds <thr...@gmail.com>

Jack.Chu

unread,
Sep 7, 2009, 5:51:54 AM9/7/09
to TopLanguage
这又是一个挑起争端的极好的议题。
C++有所谓的静态类吗?

查了一下,C#和Java的静态类是不能继承的类吧?C++可以用private ctor和dtor来模拟。其实就是以类的名义包裹的一沱
utility functions.

On 9月6日, 下午4时06分, cdredfox <cdred...@gmail.com> wrote:

Fei Yan

unread,
Sep 7, 2009, 8:55:18 AM9/7/09
to pon...@googlegroups.com
这个所谓的“缺陷”,还真第一次听闻。

莫非我的GCC生成的符号表已经超越了谭爷爷的书本,我都不记得他老人家怎么讲了... ...

2009/9/7 Thronds <thr...@gmail.com>

wang feng

unread,
Sep 7, 2009, 9:23:17 AM9/7/09
to pon...@googlegroups.com

Shuo Chen wrote:
> 初值全为0的静态数据放在BSS段,不占可执行文件的空间。
> 初值不为零的静态数据放在DATA段,增加可执行文件的大小。
> 在Linux下用可用objdump看。
> 具体可参考《程序员的自我修养——链接、装载与库》
> 久远 wrote:
>

为何不放在硬盘上,在程序启动之后第一时间加载一下?
这样以来日后即使这些数据需要改动,也只需要修改一下这个加载文件就可以了,
不需要重新编译,而且,觉得这种文件(.xml)是比较容易理解的

Wenbo Yang

unread,
Sep 7, 2009, 9:24:53 AM9/7/09
to pon...@googlegroups.com
一看兄台引用谭浩强,就知道下面该有争议了... :)

2009/9/7 Thronds <thr...@gmail.com>

在C中,从谭浩强书中知道了static定义的内部函数的优点,限制了函数的作用域。在自己开发的模块中,
如果确认函数不需要被别人的模块调用,那么定义成内部函数,将函数局部化,可以避免冲突。体现了模块化的特性。
但,需要注意的是,static函数不生成函数符号表,在运行调试等方面会有一定的缺陷。

 我也很怀疑这句话,static 函数在 symbol table 里面啊,难道兄台有别的意指?

文博
--
Wenbo YANG

Homepage ---> http://solrex.cn
Blog | Solrex Shuffling ---> http://blog.solrex.cn

Fei Yan

unread,
Sep 7, 2009, 9:38:20 AM9/7/09
to pon...@googlegroups.com
首先,我的GCC4.3.4编译结果已经表明,编译器可以很好的优化掉这个BSS膨胀的问题。

其次,对于数据放在硬盘里边的想法,牵扯到不同的设计思路了;一个显著的影响会是,程序的启动速度收到影响,因为对于ELF格式来说(PE也类似),一个program header是被精妙的设计用来可以直接map到一个page上的,因此进程创建之后,可以很高效的调整一下相关偏移指针就可以了,没有更多的磁盘I/O,没有更多的parser等;这些操作对程序员都是透明的

如果不是必须,就避免搞得太灵活。

将这样的东西都放到慵懒的xml里边持久化存储,甚至动态可修改,是否有点overkill?
如果需要考虑安全性,不想向外部暴楼我自己的这些初始数据状态,怎么办?是否要加密这个xml,写一个二进制的parser?这些活还是linker、loader可以干的更好的。

2009/9/7 wang feng <wanng...@gmail.com>

dachuan lin

unread,
Sep 7, 2009, 11:06:10 AM9/7/09
to pon...@googlegroups.com
依赖单独的编译器能力是不可靠的,这个在嵌入式环境下更是如此,还是以标准而不是厂商来考虑吧

2009/9/7 Fei Yan <skyscr...@gmail.com>

Fei Yan

unread,
Sep 7, 2009, 9:15:15 PM9/7/09
to pon...@googlegroups.com
这个我同意,嵌入式环境是个很特殊、受限的环境,而GCC几乎是Unix-alike操作系统的实际编译器标准
如果在没有MMU的环境下,关于ELF的分析可能好多都不凑效

根据我的了解,现在没有MMU的硬件已经慢慢失去广泛应用了,因此带MMU的CPU本身和这里讨论的这个问题是偏差不大的
这个优化本身我怀疑根本是和硬件环境关联不大的
不知道是否有人研究过cross-compile gcc4,尝试下arm下是否也可以取得同样的结果

我给出这个结果只是为了打消某些常规的教条,并不是非要放在BSS里边

如果从标准的角度出发,BSS何尝不是一种特殊的实现而非标准?某些executable可能并没有BSS(仅仅是道听途说,没有真正研究过)


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

莫华枫

unread,
Sep 7, 2009, 11:30:27 PM9/7/09
to pon...@googlegroups.com
static函数不同的语言是不一样的。就C++而言,static函数基本上等价于namespace的自由函数。而C#和java,没有自由函数,static函数起到了自由函数的作用。
D&E里阐述了namespace和class在语法上的等价性。
static函数和自由函数的差别在于两个方面:
1、static函数的扩展性不如自由函数。一旦一个类定义完成便无法对这些函数加以扩展,而namespace中的自由函数则可以在不触碰原有代码的基础上进行重载。
2、static函数可以利用class作为载体,在模板的traits中使用。
3、自由函数更便于表达多种数据对象的关系。比如,ComplexNumber和RealNumber的加法,是放在ComplexNumber类里好呢?还是放在RealNumber类里好呢?
从实用角度而言,我更喜欢自由函数。有利于减少单片式设计。
对于没有自由函数的语言,另当别论。

但无论是static函数,还是自由函数,作用都是相同的。在代码中,不应当把什么都作为类的non-static member。一个过程,一个算法,如果无需在完成后继续维持状态的,完全可以用一个static函数,最好是自由函数来实现。简单,明确。
更进一步,对于类,也应当尽可能减小non-static member的数量,并且提高它们的抽象度,尽可能使其正交。其他的“增殖”功能,以static函数,最好是自由函数实现。sutter和lippman对此都有很详细的阐述。

static class和static function是八杆子打不到的两样东西,放在一起是不对的。前者实际上就是语言提供的自动singleton。

不好的地方:
1,对面向对象语言中,可能破坏了面向对象的结构,因为使用静态类或者静态方法,就失去了extend的特征了。

这得看什么样的extend。如果说dynamic dispatch这类extend,static函数无法实现,除非具备multi-method。在其他方面,static函数,特别是自由函数,灵活性更大。
 
2,对于系统架构来说,可能感觉起来不是很合理。

“感觉”...
 
3,在高并发的情况中,容易导致数据出错(此项未验证,只是推测。因为是全局的。)

的确是推测,而且是错误的推测。
 
好的地方:
1,感觉使用起来方便一些 
2,不用重复的new一大堆对象,和销毁。可能在性能上略有提升。(but:但是会占据一定的内存空间)

不用new对象,这自然不错。但static函数是如何占据一定的内存空间的呢?
当你new出一个对象来的时候对象会占用堆内存,调用一个static函数的时候会吗?



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

lindach...@gmail.com

unread,
Sep 7, 2009, 10:51:07 PM9/7/09
to TopLanguage
感觉有点跑题了,呵呵,还是focus静态方法和静态类方法吧,我感觉如下:

1、从工程的角度,c语言的static function是绝妙的封装,因为如果有大量的代码重复而你不想暴露出来可以用它来封装,至于编译出来的大
小和无法调试就要看具体环境了,我想这不是选择的重点吧;

2、c++里的class static function有没有用呢?我好像看到过一个国外一个thread讨论过,认为是不如直接使用
namespace+function,因为可以使用c++模板的参数自动解析;

3、java中的class static function基本上是不得不用,我赞成上面的大大的观点,考虑到线程安全,还不如使用单一对象模式。

On Sep 8, 9:15 am, Fei Yan <skyscribe...@gmail.com> wrote:
> 这个我同意,嵌入式环境是个很特殊、受限的环境,而GCC几乎是Unix-alike操作系统的实际编译器标准
> 如果在没有MMU的环境下,关于ELF的分析可能好多都不凑效
>
> 根据我的了解,现在没有MMU的硬件已经慢慢失去广泛应用了,因此带MMU的CPU本身和这里讨论的这个问题是偏差不大的
> 这个优化本身我怀疑根本是和硬件环境关联不大的
> 不知道是否有人研究过cross-compile gcc4,尝试下arm下是否也可以取得同样的结果
>
> 我给出这个结果只是为了打消某些常规的教条,并不是非要放在BSS里边
>
> 如果从标准的角度出发,BSS何尝不是一种特殊的实现而非标准?某些executable可能并没有BSS(仅仅是道听途说,没有真正研究过)
>

> 2009/9/7 dachuan lin <lindachuan2...@gmail.com>
>
> > 依赖单独的编译器能力是不可靠的,这个在嵌入式环境下更是如此,还是以标准而不是厂商来考虑吧
>
> > 2009/9/7 Fei Yan <skyscribe...@gmail.com>


>
> > 首先,我的GCC4.3.4编译结果已经表明,编译器可以很好的优化掉这个BSS膨胀的问题。
>
> >> 其次,对于数据放在硬盘里边的想法,牵扯到不同的设计思路了;一个显著的影响会是,程序的启动速度收到影响,因为对于ELF格式来说(PE也类似),一个program
> >> header是被精妙的设计用来可以直接map到一个page上的,因此进程创建之后,可以很高效的调整一下相关偏移指针就可以了,没有更多的磁盘I/O,没有更多的parser等;这些操作对程序员都是透明的
>
> >> 如果不是必须,就避免搞得太灵活。
>
> >> 将这样的东西都放到慵懒的xml里边持久化存储,甚至动态可修改,是否有点overkill?
>
> >> 如果需要考虑安全性,不想向外部暴楼我自己的这些初始数据状态,怎么办?是否要加密这个xml,写一个二进制的parser?这些活还是linker、loader可以干的更好的。
>

> >> 2009/9/7 wang feng <wanng.fe...@gmail.com>


>
> >>> Shuo Chen wrote:
>
> >>>> 初值全为0的静态数据放在BSS段,不占可执行文件的空间。
> >>>> 初值不为零的静态数据放在DATA段,增加可执行文件的大小。
> >>>> 在Linux下用可用objdump看。

> >>>> 具体可参考《程序员的自我修养----链接、装载与库》

dachuan lin

unread,
Sep 7, 2009, 11:35:38 PM9/7/09
to pon...@googlegroups.com
奇怪,我在group里面的回复怎么没了?不管了。。。

class static function 好像不能进行参数模板类型的自动推定吧,手头上网本没有编译器,没法确定,哪位老大知道的告知一下?

2009/9/8 莫华枫 <longsh...@gmail.com>

Thronds

unread,
Sep 8, 2009, 8:08:51 AM9/8/09
to TopLanguage
自己一知半解让大家费解了
目前我理解的是,extern函数生成的函数符号表是全局性的,static函数的则是本地局部性的。static函数符号表在非本地的文件中就看不到
了,如果一样能够可见的话,那么就能够调用了啊
static函数(C中)的优点大家都说了许多,在C专家编程中非常推崇static函数,我很想知道static函数还有哪些缺点。

On 9月7日, 下午9时24分, Wenbo Yang <sol...@gmail.com> wrote:
> 一看兄台引用谭浩强,就知道下面该有争议了... :)
>

> 2009/9/7 Thronds <thro...@gmail.com>

dachuan lin

unread,
Sep 8, 2009, 8:27:43 AM9/8/09
to pon...@googlegroups.com
缺点是无法导出外面调用

2009/9/8 Thronds <thr...@gmail.com>

sagasw

unread,
Sep 8, 2009, 9:03:25 AM9/8/09
to pon...@googlegroups.com
幽默大师啊!

2009/9/8 dachuan lin <lindach...@gmail.com>
329.gif

Fei Yan

unread,
Sep 8, 2009, 9:41:05 AM9/8/09
to pon...@googlegroups.com
你说的看不见,是指代什么看不见,“人肉眼”看不见,还是二进制文件连OS的loader也看不见?debugger的能力可是比compiler unit的能力强很多的,想让它也看不见的,恐怕除了宏,别的还真不多

你的这个 “调试”造成的缺陷, 真的是你所列的“缺陷”的一种? 抑或是幽默一把?


2009/9/8 Thronds <thr...@gmail.com>

Hongzhang Liu

unread,
Sep 9, 2009, 9:14:45 AM9/9/09
to pon...@googlegroups.com
贴一下你的编译选项,g++版本。另外,你的代码中没有对data的任何形式的使用,请加上对此数组的访问代码。我在gcc 4.3.4下测试结果于vc一致。

2009/9/7 Fei Yan <skyscr...@gmail.com>:

Fei Yan

unread,
Sep 9, 2009, 10:10:23 AM9/9/09
to pon...@googlegroups.com
原来给出的VC产生很大差异的代码同样没有访问仅仅是初始化,我也没有用任何特殊的编译选项,就普通的默认-O2

刚才又试了一下,发现大致应该是该数组没有被访问导致被GCC给优化掉了(对引起的误导表示抱歉)
如果main里边加上访问代码,确实多出了4M的空间

原始的例子是照着拷贝下来的,但同样的代码(仅仅初始化而没有显示访问),VC/Gcc确实是有差异


2009/9/9 Hongzhang Liu <hongzh...@gmail.com>
Reply all
Reply to author
Forward
0 new messages