青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

loop_in_codes

低調(diào)做技術(shù)__歡迎移步我的獨(dú)立博客 codemaro.com 微博 kevinlynx

靜態(tài)庫(kù)中全局變量的初始化問(wèn)題

 

在我自己寫(xiě)的一個(gè)工廠類(lèi)實(shí)現(xiàn)中,每個(gè)產(chǎn)品會(huì)注冊(cè)創(chuàng)建接口到這個(gè)工廠類(lèi)。工廠類(lèi)使用這些
注冊(cè)進(jìn)來(lái)的創(chuàng)建接口來(lái)完成產(chǎn)品的創(chuàng)建。其結(jié)構(gòu)大致如下:

product *factory::create( long product_type )
{
    creator c = m_creators[product_type];
    return c();
}

factory::instance().register( PRODUCT_A_TYPE, productA::create );
...
factory::instance().create( PRODUCT_A_TYPE );

這個(gè)很普通的工廠實(shí)現(xiàn)中,需要寫(xiě)上很多注冊(cè)代碼。每次添加新的產(chǎn)品種類(lèi)時(shí),也需要修改
這些的注冊(cè)代碼。而恰好,這些注冊(cè)代碼可能會(huì)被放在一個(gè)統(tǒng)一的地方。為了消除這個(gè)地方
,我使用了偶然間看到的<Modern C++ design>里的做法:

const bool _local = factory::instance().register( PRODUCT_A_TYPE,...

也就是說(shuō),通過(guò)對(duì)全局常量_local的自動(dòng)初始化,來(lái)自動(dòng)完成對(duì)該產(chǎn)品的注冊(cè)。

結(jié)果,因?yàn)檫@些代碼全部被放置于一個(gè)靜態(tài)庫(kù)。最終的代碼文件結(jié)構(gòu)大致為:

lib
    - product_a.cpp : 定義了全局常量_local
    - product_a.h
    - factory.cpp
    - factory.h
exe
    - main.cpp

現(xiàn)在看起來(lái)世界很美,因?yàn)閒actory甚至不知道世界上還有個(gè)跟上層邏輯相關(guān)的product_a。
這種模塊耦合幾乎為0的結(jié)構(gòu)讓我竊喜。

悲劇的事情首先發(fā)生于,開(kāi)VC調(diào)試器,發(fā)現(xiàn)打在product_a.cpp里的斷點(diǎn)失效。就是那個(gè)總
是提示說(shuō)沒(méi)有為該文件加載調(diào)試符號(hào)。開(kāi)始還不在意,以為又是代碼和調(diào)試符號(hào)文件不匹配
的原因,折騰了好久,不得其果。

后來(lái)分析了下,發(fā)現(xiàn)這個(gè)調(diào)試提示,就像我開(kāi)著調(diào)試器打開(kāi)了一個(gè)非本工程的代碼文件,而
斷點(diǎn)就打在這個(gè)文件里一樣。也就是說(shuō),VC把我product_a.cpp當(dāng)成不是這個(gè)工程里的代碼
文件。

按照這個(gè)思路寫(xiě)些實(shí)驗(yàn)代碼,最終發(fā)現(xiàn)問(wèn)題所在:VC鏈接器根本沒(méi)鏈接進(jìn)product_a.cpp里
的代碼。表現(xiàn)出來(lái)的情況就是,該編譯單元里的全局常量(全局變量一樣)根本沒(méi)有得到初
始化,因?yàn)槲腋絝actory::register并沒(méi)有被調(diào)用到。為什么VC不鏈接這個(gè)編譯單元對(duì)應(yīng)
的目標(biāo)文件?或者說(shuō),為什么VC不初始化這個(gè)全局常量?

原因就在于,product_a.cpp太獨(dú)立了。一個(gè)在整個(gè)編譯鏈接階段都無(wú)法確定該文件是否被
使用的文件,VC就直接不鏈接了。相反,當(dāng)在factory.cpp里寫(xiě)下類(lèi)似代碼:

void test()
{
    product_a obj;
}

雖然說(shuō)test函數(shù)不會(huì)被調(diào)用,一切情況也變得正常了。好了,不扯了,給最后我的結(jié)論:

1、如果靜態(tài)庫(kù)中某個(gè)編譯單元在編譯階段被確認(rèn)為它并沒(méi)有被外部使用,那么當(dāng)這個(gè)靜態(tài)
庫(kù)被鏈接進(jìn)可執(zhí)行文件時(shí),鏈接器忽略掉該編譯單元里的代碼,那么,鏈接器自然也不會(huì)為
該編譯單元里出現(xiàn)的全局變量常量生成初始化代碼(關(guān)于這部分初始化代碼可以閱讀
<linker and loader>一書(shū));
2、上面那條結(jié)論存在一種傳染性,意思是,當(dāng)可執(zhí)行文件里的代碼使用到靜態(tài)庫(kù)中文件A里
的代碼,A里又有地方使用到B里的代碼,那么B依然會(huì)被鏈接。這種依賴(lài)性,應(yīng)該可以讓編
譯器在編譯階段就發(fā)現(xiàn)(顯然,上面我舉的例子里,factory只有在運(yùn)行期間才會(huì)依賴(lài)到
product_a.cpp里的代碼)

posted on 2010-01-17 19:34 Kevin Lynx 閱讀(15771) 評(píng)論(19)  編輯 收藏 引用 所屬分類(lèi): c/c++通用編程

評(píng)論

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-17 20:08 OwnWaterloo

試試在product_a.cpp中, 將:
const bool _local = factory::instance().register( PRODUCT_A_TYPE,...
改為:
extern const bool local_ = factory::instance()...
或者:
namespace {
extern const bool local = ...
}

可能有效,可能無(wú)效。


即使有效,依然不能保證local的初始化順序。main之后執(zhí)行的代碼,可以保證所有產(chǎn)品已經(jīng)被注冊(cè),main之前沒(méi)有保證。
  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-17 22:41 LOGOS

const bool _local = factory::instance().register( PRODUCT_A_TYPE,...
wow, are u crazy?  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-17 23:00 Kevin Lynx


@OwnWaterloo
@LOGOS
加extern是什么意思?文章中的例子,只是因?yàn)殒溄悠鳑](méi)有為靜態(tài)庫(kù)中的全局對(duì)象生成初始化代碼。我也并不關(guān)心每一個(gè)local的初始化順序,因?yàn)樗麄兪侨值模运麄兛隙〞?huì)先于main被初始化。整個(gè)文章的意思,其實(shí)是說(shuō),鏈接器并沒(méi)有生成這個(gè)自動(dòng)初始化的代碼,因?yàn)殒溄悠饔X(jué)得這幾個(gè)“沒(méi)有”被使用的全局對(duì)象不需要,所以就沒(méi)生成。

  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-17 23:04 OwnWaterloo

@Kevin Lynx
在C++中, 非local的const對(duì)象, 默認(rèn)是staic鏈接……

a.cpp
int g_i;

雖然g_i也不一定能被添加到最終代碼中, 但機(jī)會(huì)應(yīng)該比:

a.cpp
static int g_i; 要大。
  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-18 04:19 藥品中國(guó)網(wǎng)

很好 學(xué)習(xí)了。  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-18 08:52 Kevin Lynx

@OwnWaterloo
這個(gè)機(jī)會(huì)是什么意思?  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-19 12:06 OwnWaterloo

@Kevin Lynx
編譯器根據(jù)什么規(guī)則來(lái)判斷某個(gè)沒(méi)有被使用的符號(hào)可以不必鏈接到binary中?
這個(gè)規(guī)則我不了解, 可能C++標(biāo)準(zhǔn)有描述, 也可能沒(méi)有。

我只是猜想 :
1. 如果某個(gè)extern符號(hào)沒(méi)有被鏈接到binary中, 那將其改為static, 應(yīng)該也不會(huì)被鏈接到binary中。
2. 如果某個(gè)static符號(hào)沒(méi)有被鏈接到binary中, 那將其改為extern, 也許就會(huì)被鏈接到binary中。

這就是機(jī)會(huì)的意思。

btw, 改為extern const 有效么?
  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-20 09:14 Kevin Lynx

@OwnWaterloo
一樣的。  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-01-20 19:44 李現(xiàn)民

我以前也試過(guò)這樣的方法, 項(xiàng)目用的是vc6,只debug版本下對(duì)象是可以生生的,release版本中就被人優(yōu)化掉了,沒(méi)有找到保持這種級(jí)別低耦合度的替代方案。
到現(xiàn)在為止, 我寫(xiě)的那個(gè)factory類(lèi)再也沒(méi)有用過(guò),因?yàn)榭床坏絻?yōu)勢(shì)在哪里, 還不如現(xiàn)寫(xiě)一個(gè)工廠來(lái)得清晰  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-02-09 19:44 金慶

Issues with static variables in static libraries
( http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/5c5ee89d-2a38-483d-8550-484550901170 )

You can use the /INCLUDE linker option:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_.2f.INCLUDE.asp

Or you place a #pragma in your code like this:
#pragma comment(linker, "/include:SymbolToUse")
  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-02-10 12:14 李現(xiàn)民

@金慶
不好使
我想應(yīng)該是這個(gè)問(wèn)題:
Only problem is that the symbol is not very...simple. I have a class called fxAttributeEditor, but you can't just do /include:fxAttributeEditor. The symbol is actually:

??_C@_0BC@OFGGEBAJ@fxAttributeEditor?$AA@

And that does work, but having to add that seems like a terrible coding decision. It seems like going the dynamic library route would be far better. I've had a variety of really good reasons for not wanting to do that. I'm not against DLLs, but in some cases (like mine) I don't believe it's the best choice. Is there not any better way to go about this?

Thanks,

這是引用原文, 大概意思是“不能夠在#pragma comment(linker, /include:)中直接使用你定義的那個(gè)變量名”,因?yàn)閏++編譯時(shí)會(huì)將其改為??_C@_0BC@OFGGEBAJ@fxAttributeEditor?$AA@這樣的的形式。

我不知道是不是真的這樣, 但我的實(shí)驗(yàn)結(jié)果是找不到我自己定義的變量名  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-02-10 15:52 金慶

@李現(xiàn)民
試了一下,確實(shí)如此。我打開(kāi)lib文件查到了加了前后綴的變量名,然后在主調(diào)程序中添加/include指令,這樣才有效。我原來(lái)以為只需加在靜態(tài)庫(kù)中呢。實(shí)際上,靜態(tài)庫(kù)中加不加/include指令,都會(huì)輸出符號(hào)。但是static變量是無(wú)論如何都不會(huì)輸出符號(hào)的。/include指令與引用該符號(hào)的作用一樣。所以我的結(jié)論是應(yīng)該輸出一個(gè)init()函數(shù)來(lái)初始化靜態(tài)庫(kù)。  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2010-02-10 16:43 Kevin Lynx

@金慶
@李現(xiàn)民
3q for your comments.
今天隨便看了個(gè)文檔http://linux.chinaunix.net/bbs/thread-910296-1-1.html,<Linker Algorithm.pdf>恰好在里面看到和我這里提到的相同的2點(diǎn)結(jié)論  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2011-11-07 01:15 溪流

這個(gè)問(wèn)題最終解決了嗎?  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2011-11-07 09:46 Kevin Lynx

@溪流
解決辦法就是換成常規(guī)方法:顯示初始化。  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2011-11-07 10:35 李現(xiàn)民

@Kevin Lynx
這個(gè)問(wèn)題后來(lái)我試過(guò),在我的項(xiàng)目里( 前面提到的,使用了VC6),問(wèn)題出在使用singleton生成單個(gè)factory對(duì)象的地方。如果將factory的構(gòu)造函數(shù)設(shè)計(jì)為private,同時(shí)提供一個(gè)類(lèi)get_instance()的public static方法,會(huì)產(chǎn)生多個(gè)factory實(shí)例。具體表現(xiàn)就是,register()函數(shù)的確執(zhí)行了, 但是所有的注冊(cè)內(nèi)容都注冊(cè)到了第一個(gè)factory對(duì)象身上,等到運(yùn)行期使用create方法的時(shí)候,使用的卻是后面新生成的factory對(duì)象,因此會(huì)發(fā)生沒(méi)有注冊(cè)過(guò)的假象。

解決方法為:將factory()構(gòu)造函數(shù)聲明為public,在factory類(lèi)外面定義一個(gè)singleton函數(shù),并一直使用這個(gè)函數(shù)進(jìn)行注冊(cè)與創(chuàng)建。但這種方法的缺點(diǎn)是你無(wú)法從語(yǔ)法上確保所有用戶(hù)使用的都是這個(gè)singleton對(duì)象。

懷疑為VC6的bug,不過(guò)由于已經(jīng)基本滿足了需要,未繼續(xù)深究。  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2013-06-16 11:14 戴進(jìn)

在頭文件中

#ifndef _DEF_AUTO_FACTORY
#define _DEF_AUTO_FACTORY
static CFactory __AutoFactory;
#endif

這樣能解決問(wèn)題,但是間接的也導(dǎo)致了你的這個(gè)類(lèi)被公開(kāi)了。  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2013-06-16 13:36 戴進(jìn)

我暫時(shí)性是這么解決自動(dòng)初始化靜態(tài)庫(kù)的。


a.cpp中,有一個(gè)類(lèi)

class a
{
public:
a()
{
...這里初始化
}

~a()
{
...這里做釋放
}

bool _LinkProc(){return true;}
//這個(gè)函數(shù),也就是為了鏈接用的。
};

a m_a;//全局變量

bool b = m_a._LinkProc();
//實(shí)際上光是這樣,也還是不會(huì)鏈接,那怎么辦呢,問(wèn)了下度娘,她說(shuō),要訪問(wèn)到的全局變量,才會(huì)鏈接,那么最后我們到頭文件中。

h文件中
extern bool b;//注意extern只是引用,不等同于訪問(wèn)。
static bool c = b;//這里對(duì)b的訪問(wèn),就自動(dòng)鏈接到



  回復(fù)  更多評(píng)論   

# re: 靜態(tài)庫(kù)中全局變量的初始化問(wèn)題 2014-05-15 19:35 HK

兄弟,這個(gè)問(wèn)題我也遇到了,我采用的方法是新建一個(gè)新的.cpp文件(for_register.cpp)
然后“const bool _local = factory::instance().register( PRODUCT_A_TYPE,... ”這個(gè)定義在 for_register.cpp這個(gè)文件里
最后在一定能被鏈接進(jìn)去的一個(gè).cpp里 include " for_register.cpp"
這樣基本上就解決了。
你每新增一個(gè)產(chǎn)品就要到 for_register.cpp里面去注冊(cè)一下。  回復(fù)  更多評(píng)論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久国产精品一区二区三区四区| 国产一区二区三区高清在线观看| 亚洲黄色天堂| 欧美天堂亚洲电影院在线观看| 日韩一区二区福利| 国语自产偷拍精品视频偷| 久久精品中文| 欧美成人资源网| 午夜在线精品偷拍| 久久gogo国模裸体人体| 亚洲国产成人午夜在线一区| 亚洲精品永久免费| 国产情侣久久| 亚洲国产欧美一区二区三区同亚洲| 蜜桃av噜噜一区| 亚洲一区欧美二区| 久久久噜噜噜久噜久久| 欧美一区二区三区免费观看视频| 亚洲欧美日韩视频一区| 午夜一级久久| 亚洲国产视频直播| 一级成人国产| 在线日韩av片| 一区二区三区免费在线观看| 狠狠色狠狠色综合| 日韩视频中文| 亚洲高清一区二| 亚洲欧美日本在线| 另类亚洲自拍| 欧美成人免费网站| 久久久久久网址| 欧美午夜电影在线| 欧美成人精品高清在线播放| 国产精品乱子久久久久| 亚洲黄一区二区| 国产综合久久| 中文无字幕一区二区三区| 亚洲国产精品第一区二区三区| 亚洲一区二区三区精品视频| 欧美大片91| 国产日韩欧美在线看| 久久综合国产精品| 国产亚洲欧美日韩美女| 一本高清dvd不卡在线观看| 亚洲国产裸拍裸体视频在线观看乱了中文 | 久久国产精品99国产精| 亚洲深夜激情| 欧美激情在线| 欧美大色视频| 亚洲国产老妈| 久久久久久久综合日本| 久久精品色图| 日韩视频一区二区| 老司机精品视频网站| 久久亚洲私人国产精品va媚药| 国产精品素人视频| 亚洲宅男天堂在线观看无病毒| 99亚洲一区二区| 欧美日本精品| 亚洲精品一区二区在线观看| 亚洲九九九在线观看| 女女同性女同一区二区三区91| 免费成年人欧美视频| 亚洲欧美日韩一区在线观看| 一区二区av| 免费久久99精品国产自| 麻豆免费精品视频| 在线观看欧美激情| 久久精品亚洲热| 国精品一区二区三区| 久久av在线| 欧美一级在线播放| 国产女优一区| 久久精品国产视频| 欧美黄色免费| 日韩一级视频免费观看在线| 欧美日韩免费观看一区| 一本色道久久88亚洲综合88| 欧美国产日韩一区二区| 亚洲美女91| 欧美日韩欧美一区二区| 亚洲伊人色欲综合网| 久久精品一本| 亚洲精品黄网在线观看| 欧美视频日韩视频在线观看| 亚洲一区二区高清| 可以看av的网站久久看| 亚洲国产精品一区制服丝袜| 欧美日韩国产在线播放网站| 亚洲在线视频观看| 欧美成年视频| 亚洲欧美日韩成人| 极品日韩av| 欧美日韩国产系列| 久久激情五月丁香伊人| 最新日韩av| 久久不见久久见免费视频1| 香蕉免费一区二区三区在线观看 | 米奇777超碰欧美日韩亚洲| 欧美超级免费视 在线| 99热这里只有精品8| 国产女人水真多18毛片18精品视频| 久久婷婷丁香| 一本色道**综合亚洲精品蜜桃冫| 久久久久久久欧美精品| 免费日本视频一区| 亚洲精品国产精品国自产观看| 欧美色欧美亚洲另类二区| 欧美在线网站| av成人老司机| 欧美成人激情在线| 欧美亚洲免费| 亚洲一区免费网站| 亚洲精品乱码久久久久| 国产在线国偷精品产拍免费yy| 欧美日韩成人精品| 免费观看欧美在线视频的网站| 香蕉久久夜色精品| 亚洲桃花岛网站| 亚洲欧洲一区二区三区久久| 久久久女女女女999久久| 亚洲免费在线视频| 一区二区三区欧美亚洲| 亚洲日韩中文字幕在线播放| 国产一区清纯| 国产香蕉久久精品综合网| 一区二区三区四区五区视频| 亚洲大胆视频| 欧美高清视频在线播放| 久久久综合精品| 久久久www免费人成黑人精品 | 国产精品女主播在线观看| 欧美激情第二页| 欧美成人午夜影院| 免费在线视频一区| 欧美黄色aaaa| 欧美一区二区三区精品电影| 国产精品午夜国产小视频| 国产精品成人免费视频 | 鲁大师成人一区二区三区| 久久国产精品久久久久久电车| 亚洲欧美激情一区| 午夜欧美大尺度福利影院在线看| 亚洲免费网站| 久久成人av少妇免费| 久久久成人网| 美女国内精品自产拍在线播放| 老司机久久99久久精品播放免费| 久久综合激情| 欧美精品乱码久久久久久按摩| 欧美韩日亚洲| 亚洲国产第一| 国产亚洲欧美日韩一区二区| 国模精品一区二区三区色天香| 激情文学一区| 亚洲免费av片| 香蕉av777xxx色综合一区| 久久久久久有精品国产| 国产专区欧美精品| 亚洲国产精品成人久久综合一区| 亚洲人成人一区二区三区| 这里只有精品视频| 久久狠狠久久综合桃花| 免费成人高清在线视频| 亚洲破处大片| 亚洲综合视频1区| 免费一级欧美片在线播放| 久久一区激情| 久久久久久综合网天天| 亚洲高清资源综合久久精品| 久久综合九色欧美综合狠狠| 欧美激情一区| 国产麻豆精品在线观看| 亚洲国产日日夜夜| 午夜精品国产| 亚洲电影下载| 亚洲欧美日韩一区二区| 欧美成人综合| 国产视频久久久久| 妖精成人www高清在线观看| 久久国产日韩欧美| 亚洲精品综合精品自拍| 欧美在线播放一区| 欧美视频在线看| 亚洲欧洲日韩在线| 久久久久久精| a4yy欧美一区二区三区| 久久一二三区| 国产一区二区三区在线观看免费视频| 亚洲美女视频在线观看| 久久人人九九| 亚洲一级影院| 欧美日韩精品一区| 亚洲经典在线| 毛片av中文字幕一区二区| 午夜久久电影网| 在线亚洲欧美| 欧美日韩免费在线| 99视频在线观看一区三区| 亚洲视频在线观看|