高手请进:如何保证init函数被第一个执行?先于main和static变量

jmppok 2014-05-09 10:39:56
有一个日志的初始化函数init_log()
很多模块都要用到日志,这就需要init_log()在进程启动后,第一个被执行。
在main函数之前, 甚至要在所有static变量被初始化之前。
请高手指导:有没有什么好的方法?
windows下如何处理?
linux下如何处理?
...全文
534 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
jmppok 2014-05-15
  • 打赏
  • 举报
回复
引用 27 楼 unituniverse2 的回复:
[quote=引用 楼主 jmppok 的回复:]
上面那个看了不要嫌烦,凡碰到此类问题,我故意等你结了贴后再发,反正这种事除了惹别人不高兴外对本人没有任何好处。忠言逆耳,自己看着办好了。。。 [/quote] 学习了,你很厉害啊
unituniverse2 2014-05-10
  • 打赏
  • 举报
回复
引用 楼主 jmppok 的回复:
上面那个看了不要嫌烦,凡碰到此类问题,我故意等你结了贴后再发,反正这种事除了惹别人不高兴外对本人没有任何好处。忠言逆耳,自己看着办好了。。。
unituniverse2 2014-05-10
  • 打赏
  • 举报
回复
其实不如把这问题反过来看: 什么样的设计导致你的C++程序中会有大量的静态和全局对象的?? 一般设计良好的OOP程序中全局变量都是用来做为进程全局数据的入口而不是直接把对象定义在全局数据区。几乎所有的数据都是在main启动后再分配的。而业务逻辑的“入口函数”则是被main函数启动加载的 这样的话日志、错误处理等模块就成了特例了,可以被main加载也可以定义成全局对象。 C++的全局对象有个要求就是任意的对象之间不能有依赖关系,比如a,b两个全局对象,所属的类型分别是TA、TB,假如TB需要TA做初始化的参数TB(const TA & init)那么这样的设计就不好了。 OOP中的任何对象都是具有生命期的,如果一个对象仅仅和业务逻辑有直接关系那么其生命期就不应该超过main的(所以日志和程序管理器对象的生命期可以超过main函数的作用域,因为他们不是仅仅业务逻辑关系的而是具有进程控制方面的需求)。当你因为懒得考虑架构问题而把全局和静态对象弄得到处都是其实就是隐含的表示你放弃了这些对象仅仅是业务逻辑相关的特性。之后出了任何像此类生命期相关的设计问题也怨不得谁,只能考虑修改设计到它原本应该有的样子了。。。
zybjtu 2014-05-09
  • 打赏
  • 举报
回复
这样的需求必然不是好需求。 你放心大胆在main里面用就对了
Symfund 2014-05-09
  • 打赏
  • 举报
回复
这个问题提得很有技术含量!
FancyMouse 2014-05-09
  • 打赏
  • 举报
回复
引用 8 楼 jmppok 的回复:
[quote=引用 7 楼 ri_aje 的回复:] 第一次使用的时候初始化就可以了吧。
这个也可以。但是需要每次都要判断。 log模块可能被其他所有模块频繁使用,每次都判断感觉不太好。[/quote] 瓶颈不会在那里的。放心这么用。
jmppok 2014-05-09
  • 打赏
  • 举报
回复
引用 6 楼 j8daxue 的回复:
windows下试试这样

#define SECTION_NAME ".CRT$XCA1"
#pragma section(SECTION_NAME, long, read)
void foo()
{
    printf("foo called\n");
}
typedef void (__cdecl* PF)()
__declspec(allocate(SECTION_NAME )) PF initorA1[] = { foo };
多谢,这个我试试看。
jmppok 2014-05-09
  • 打赏
  • 举报
回复
引用 7 楼 ri_aje 的回复:
第一次使用的时候初始化就可以了吧。
这个也可以。但是需要每次都要判断。 log模块可能被其他所有模块频繁使用,每次都判断感觉不太好。
ri_aje 2014-05-09
  • 打赏
  • 举报
回复
第一次使用的时候初始化就可以了吧。
j8daxue 2014-05-09
  • 打赏
  • 举报
回复
windows下试试这样

#define SECTION_NAME ".CRT$XCA1"
#pragma section(SECTION_NAME, long, read)
void foo()
{
    printf("foo called\n");
}
typedef void (__cdecl* PF)()
__declspec(allocate(SECTION_NAME )) PF initorA1[] = { foo };
  • 打赏
  • 举报
回复
自定义入口函数
jmppok 2014-05-09
  • 打赏
  • 举报
回复
引用 2 楼 flyrack 的回复:
全局变量在编译期就存在了 不是在执行期执行的
可能没理解我的意思。 编译出来一个的是一个lib库,没有人使用加载它,虽然它确实存在,但是并没有加载进内存中,没有被初始化的。 只有在一个进程调用它的情况下,进程启动的时候,他才会被调进内存中,并且初始化。这时候它才有了意义。
jmppok 2014-05-09
  • 打赏
  • 举报
回复
执行的时候才初始化吧。 class A { public: A() { printf("construct A\n"); } }; static A a; 通过声明static变量,可以在该变量初始化时,即构造函数中执行一些code。 当然该过程是在main函数执行之前的。 C++的一个小技巧。
flyrack 2014-05-09
  • 打赏
  • 举报
回复
全局变量在编译期就存在了 不是在执行期执行的
jmppok 2014-05-09
  • 打赏
  • 举报
回复
static 可以在main()之前执行 如果要在static中用log,log就必须在static之前初始化。 该如何做? 请大神们赐教。
贵子 2014-05-09
  • 打赏
  • 举报
回复
在写日志的接口里判断是否已经调用init_log,如果没有,则调用就好了 这样是最安全和简单的
hemmingway 2014-05-09
  • 打赏
  • 举报
回复
风_流沙 2014-05-09
  • 打赏
  • 举报
回复
学习了
骑着乌龟漫步 2014-05-09
  • 打赏
  • 举报
回复
xiejin90314 2014-05-09
  • 打赏
  • 举报
回复
放在Global.asax里Application_start里面吧
加载更多回复(8)

65,207

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧