外部或static变量的生存期长于main()函数?
时间:2010-06-28
来源:互联网
- #include <stdio.h>
-
- main( )
- {
- int c ;
- char buf[BUFSIZ];
- setbuf(stdout ,buf);
- while((c=getchar()) != EOF)
- putchar(c);
- }
他提出的一种改正方案是:把buf改为在函数外部定义或定义为局部的 static char buf[BUFSIZ];
这在本质上是假设了外部或static变量的生存期长于main()函数
我认为这是错误的
想听听大家的高见
作者: pmerofc 发布时间: 2010-06-28
作者: 没本 发布时间: 2010-06-28

作者: pmerofc 发布时间: 2010-06-28
如果你认为main()就是进程的起点,main()返回就是进程的终点,当然可以认为《C 陷阱与缺陷》里是错的。
作者: 没本 发布时间: 2010-06-28
static变量,我认为他的生存期从加载器将程序加载完毕后开始,而main则是程序开始执行后开始。
那个《Linux编程一站式学习》有讲到,其实main函数是被一段汇编代码调用的,这段汇编代码生成的目标文件会被链接器链接。
作者: zhaohongjian000 发布时间: 2010-06-28
退一步讲,即使不认为main()返回就是进程的终点
难道Andrew Koenig的看法就成立么?
我还是看不出他说的有什么根据
作者: pmerofc 发布时间: 2010-06-28
static变量,我认为他的生存期从加载器将程序加载完毕后开始,而main则是程序开始执行后开始。
---------------------------------------------------------------------------------------------
我认为如果我这句没说错,是可以作为依据的。拥有静态生存期的变量的初始化应该是由加载器在加载过程中完成,不属于程序执行的流程。既然程序还未执行就以存在,自然生存期更长了。
同样的,拥有静态生存期的变量的回收也不属于程序执行的流程,程序执行完后由系统负责。
作者: zhaohongjian000 发布时间: 2010-06-28
作者: 没本 发布时间: 2010-06-28
没本 发表于 2010-06-28 21:51
谢谢
要是汇编就没必要了
作者: pmerofc 发布时间: 2010-06-28
没本正解!
maij()退出后,操作系统会做一些清理工作。
在程序退出前,清理程序的资源,然后再消除虚拟内存和物理内存之间的映射。而static变量放在全局数据段里。清理资源包括关闭/flush文件等,然后才是回收内存。
从内核源码来看,至少linux和symbian os是这么干的。
作者: fera 发布时间: 2010-06-28
static变量,我认为他的生存期从加载器将程序加载完毕后开始,而main则是程序开始执行 ...
zhaohongjian000 发表于 2010-06-28 21:43
好吧。
就按你的思路说下去
问题在于“加载完毕”和“开始执行 ”有间隙吗?(以及执行结束与卸载完毕)
这个间隙可以做什么?
作者: pmerofc 发布时间: 2010-06-28
- $ cat n.cpp
- #include<stdio.h>
- struct gb
- {
- gb() { puts("hi main()\n"); }
- ~gb() { puts("bye main()\n"); }
- } g;
- int main()
- {
- puts("main: hi all\n");
- return 0;
- }
- $ g++ n.cpp -o n
- $ ./n
- hi main()
-
- main: hi all
-
- bye main()
作者: 没本 发布时间: 2010-06-28
就按你的思路说下去
问题在于“加载完毕”和“开始执行 ”有间隙吗?(以及执行 ...
pmerofc 发表于 2010-06-28 21:55
这个超出范围了。我没有看过任何一个加载器的实现,加载完成后应该(猜的)跳转到程序入口开始执行。进程执行完毕系统怎么回收都行,可以立刻回收,也可以等一会,完全是系统的事了。总之这个超出语言本身范围了。我猜C的ISO文档上应该有说明静态生存期变量的有效范围吧,我英语不好,就不自己看了。
作者: zhaohongjian000 发布时间: 2010-06-28
- $ cat e.c
- #include <stdio.h>
- #include <stdlib.h>
-
- void bye(void) { puts("bye main()\n"); }
-
- int main(void)
- {
- atexit(bye);
- puts("main: hi all!\n");
- return 0;
- }
-
- $ gcc -o e e.c
- $ ./e
- main: hi all!
-
- bye main()
-
- $
作者: 没本 发布时间: 2010-06-28
例子很有趣,谢谢
可惜是C++的
作者: pmerofc 发布时间: 2010-06-28
就知道你会这么说,我才先发一个C++,我又料中了。看14楼。
作者: 没本 发布时间: 2010-06-28
就知道你会这么说,我才先发一个C++。看14楼。
没本 发表于 2010-06-28 22:07
问题的核心在于,
如果存在时间间隔
那么在这个间隔之中,谁可以做什么?
作者: pmerofc 发布时间: 2010-06-28
作者: 没本 发布时间: 2010-06-28
没本 发表于 2010-06-28 22:12
?
这到底是什么时候
例如?
作者: pmerofc 发布时间: 2010-06-28
void exit(int status);
Causes the program to terminate normally. First the functions registered by atexit are called, then all open streams are flushed and closed, and all temporary files opened with tmpfile are removed. The value of status is returned to the environment. If status is EXIT_SUCCESS, then this signifies a successful termination. If status is EXIT_FAILURE, then this signifies an unsuccessful termination. All other values are implementation-defined.
作者: zhaohongjian000 发布时间: 2010-06-28
作者: 没本 发布时间: 2010-06-28
没本 发表于 2010-06-28 22:18
“你既然承认了main()之后还有函数运行。”这个我没承认,实际上恰恰是我希望弄清楚的
“main(){char buf;}在main()之后无效,这是常识。”,这个没问题,我不反对这个常识
谢谢
作者: pmerofc 发布时间: 2010-06-28
3 An object whose identifier is declared with external or internal linkage, or with the
storage-class specifier static has static storage duration. Its lifetime is the entire
execution of the program and its stored value is initialized only once, prior to program
startup.
作者: OwnWaterloo 发布时间: 2010-06-28
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28