C_and_CPP 板


LINE

我遇到一个奇怪的问题, 就是当我在 linux 使用 ar 把 .o 包成 .a 的时候, 被 ar 包装过的 class 所包含的 static data member 不会初始化…… 比方说我有一个档案 foo.cpp 是这样 ┌────────────────────────────────────┐ int f() {std::cout << "f()" << std::endl ;return 17 ;}| │ class Foo {static int n ;}| │ int Foo::n = f() ; /* 初始化 static member */└────────────────────────────────────┘ 经过下面的 build 步骤…… g++ -c foo.cpp -o foo.o ar -cr foo.a foo.o g++ main.cc foo.a 执行 a.out 之後,并没有印出 "f()"。 但是如果我直接使用 foo.o, 那麽就会正常的印出 "f()"。 比方说这样…… g++ -c foo.cpp -o foo.o g++ test.cc foo.o 我好困惑喔。 会有这个问题是因为我在使用 google test 的时候, 发现如果我的 test case 被 ar 包过以後,测试的时候会没有测到那些项目, google test 写 test case 的时候,其实是透过 macro 把 test case 转成 class。 而 test 的 code 被呼叫的时机, 实际上是这个 class 某一个 static member 初始化的时候会呼叫一个函数, 就像我上面的码一样,於是我怀疑 ar 会让 static member 的初始化被跳过, 後来发现果然是这样... 虽然说这个 class 只有在这个档案里面存在, 所以如果没被用到的话,被略过好像也没差。 但是为什麽 ar 之後就会略过呢? 直接拿 .o 来 link 又为什麽就不会被略过? 囧困,请前辈开示。 OS: 小红帽 Compiler: gcc 3.3 -- To iterate is human, to recurse, divine. 递回只应天上有, 凡人该当用回圈.   L. Peter Deutsch --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 118.160.114.40
1F:→ tinlans:先不管 ar,你怎麽确定 std::cout 比 Foo:n 先初始化? 10/30 02:12
2F:→ yoco315:有道理耶.. 这下更窘困了.... 10/30 02:13
3F:→ yoco315:那,先不管ar,googletest会显示测试结果,告诉我们有几个 10/30 02:15
4F:→ yoco315:test case 被执行,几个成功几个失败.. 10/30 02:15
5F:→ yoco315:但是显示出来的结果都是 0 个,代表根本没有东西被执行.. 10/30 02:16
6F:→ yoco315:喔,还有可能是因为main在ar之前初始,导致testcaes没注册 10/30 02:18
7F:→ yoco315:阿 该不会真的是「静态成员初始化顺序」这个洞吧.. 10/30 02:19
8F:→ tinlans:我跟 googletest 不熟所以不知道,但要测试 ar 会不会略过 10/30 02:22
9F:→ tinlans:初始化应该有更直接的方法,像是在 main 直接 cout 值。 10/30 02:22
10F:推 BDFishX:刚我试过,只要存取到Foo::n,就会呼叫f(),没用到就略过 10/30 02:26
11F:→ tinlans:那是理所当然的,linker 有义务去除不必要的 symbol。 10/30 02:32
12F:→ tinlans:实测也是跟楼上一样,用 ar 封装成 .a 有用到必会初始化。 10/30 02:35
13F:→ tinlans:只是 cout 的位置是在 main() 里。 10/30 02:35
14F:→ tinlans:gdb 也拦得到 foo(),确定有进去。 10/30 02:36
15F:→ yoco315:那我还是有问题,linker会去除不必要的symbol.. 10/30 02:50
16F:→ yoco315:那为什麽我直接 link foo.o 的时候还是会初始化 @@? 10/30 02:50
17F:→ tinlans:看你的主程式内容而定吧,我是觉得都有初始化到才对,只是 10/30 14:22
18F:→ tinlans:cout 初始化顺序不一样造成你印不出来,用 gdb 拦来看最快 10/30 14:22
19F:→ tinlans:,如果没 f 这个 symbol 那 gdb 应该直接跟你说不存在。 10/30 14:22
20F:→ tinlans:用 nm 直接查也行。 10/30 14:23
21F:→ BDFishX:在没有存取到Foo::n的情况下,如果我用gdb去对f设break 10/30 15:42
22F:→ BDFishX:用foo.a会发生gdb找不到f,foo.o则gdb可以找的到f 10/30 15:42
23F:→ BDFishX:很明显g++对foo.a和foo.o的结果是不太一样的 10/30 15:42
24F:→ BDFishX:我也对这很好奇为什麽会有这样的差别~~~@@ 10/30 15:42
25F:→ yoco315:我把cout改成开一个档案来写,结果.a的时候那个档案没出来 10/30 20:58
26F:→ yoco315:所以很肯定是没有初始化 O_O 不是顺序的问题,真的好神奇 10/30 20:58
27F:→ yoco315:其实也没什麽,只是这样我gtest就不能包在ar里面用.. :D 10/30 20:58
28F:→ yoco315:确定状况会是怎样就好了 O_O.. 没差.. 10/30 20:59







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BuyTogether站内搜寻

TOP