帖子

目前显示的是 十月, 2016的博文

如何在VC++中强制引用静态库里的所有全局变量

图片
这个坑啊…… 真是历史悠久名声昭著了。

假如你的exe用到了一个静态库,而这个静态库有一些全局变量。那么这些全局变量未必会被引用到这个exe当中。

举个例子:
Foo.h:
===================
class Foo
{
public:
Foo();
};
===================
Foo.cpp: =================== #include "Foo.h" #include <stdio.h>

Foo::Foo() { printf("hello"); }
static Foo foo; =================== 假如Foo.cpp是被编译成静态库,那么链接的时候可能没有foo这个变量,从而也不会有"hello"输出。

有些人写代码喜欢用全局变量来实现singleton,并且期望这些singleton的构造函数会在main函数之前被调用。呵呵…… 到了vc这里就不灵了。

可是,如果万一他的代码就是这样,你又没法改,办法还是有的。
办法1:链接的时候加 /WHOLEARCHIVE 。这是VS 2015 update 2以后才有的选项办法2:
1. 要以项目引用的方式来引用静态库,而不是把.lib文件作为input给linker
2. 把“link library dependencies” 和 "Use link library dependency inputs” 这两个选项设置成true。





如何正确的关闭已打开的文件

如果一个文件是以只读的方式打开的,那么忘记关闭的后果是:句柄泄露。通常来说这不是太大的问题。
如果一个文件是以可写的方式打开的,那么忘记关闭的后果是:除了句柄泄露以外,写进去的东西可能会丢失。并且,如果关闭了,但是忘记检查close(或fclose)函数的返回值,也会有丢数据的风险。

要注意点什么? 写文件的时候,要手动关,不要依赖于析构函数。用RAII来管理IO资源是非常愚蠢的。如果fclose出现在析构函数里,那么通常就是一个错误。因为析构函数不能抛异常,如果fclose返回非0的值,你很难把这个错误报告出去。出错不可怕,最可怕的是出错了但是你却不知道。比如,你的程序每天自动生成一个config文件然后自动推送到线上每台机器。结果有一天,生出来的config文件缺了一块,但是你却不知道,而这个config却被推送出去了。

什么时候fclose会返回非0值? 比如,硬盘满了。再比如,有些机器的硬盘会有一些临时故障,会导致写入偶尔失败。而这种临时故障不一定会产生报警。其实我们希望一旦有这样的问题发生,这些机器能赶紧被应用程序发现,然后从系统中剔除出去。
正确的该怎么写? FILE* fd = fopen("xxx.txt","w"); if(!fd) return; try{   //do normal io stuffs    ...  }catch(std::exception& ex){    if(fclose(fd)){       //....?    } } if(fclose(fd)) throw std::runtime_error("err");
问题来了,如果我们想把fclose失败这件事情报告出去,就得在处理异常的时候又抛出新的异常。该怎么办?遗憾的是,C++中对于这样的问题,并没有标准的做法。

Java是怎么处理这样的问题? Java7为此特地推出了Suppressed Exceptions. 比如下面的代码: package testjava; import java.io.Closeable; import java.io.IOException; public class T1 { static class A implements Closeable{ @…

人民币与IMF特别提款权(SDR)

图片
最近关于人民币被纳入IMF的特别提款权的讨论很热,我认同这个观点:“它的象征意义大于实际意义。”

SDR是布雷顿森林体系的产物,在2009年以前从未发挥过实际作用。在布雷顿森林体系时代,各国央行为了维持本国货币与美元之间的固定利率,不得不储备大量美元。于是SDR就被设计出来,作为外汇储备的一种。可惜它还尚未发挥实际作用,固定汇率制度就倒台了,于是SDR也就被尘封起来。然而若干年后,中国崛起,中国央行长久以来选择了人民币和美元之间的固定汇率制度。如下图:

为了干预汇率以及强制结汇,中国央行不得不储备大量的美元,代价是每年得为此付出高昂的成本。2008年之后,美元大幅贬值,但中国央行继续增加美元外汇储备大量购买美国国债,于是遭到很多质疑。于是央行行长周小川就瞄准了SDR。2009年3月,周小川在中国人民银行网站上发文《关于改革国际货币体系的思考》,文中建议“创造一种与主权国家脱钩、并能保持币值长期稳定的国际储备货币,从而避免主权信用货币作为储备货币的内在缺陷”。这种货币指的就是SDR。它希望在外汇储备资产中,增加SDR的比重,减少美元,以降低美国对中国的货币经济影响。

但SDR不是你想买就能买的,它的发行量非常小。当时SDR在全球的发行量只有20亿美元,中国拥有4%,大约8千万,和其上万亿的外汇储备相比不值得一提。为了提高SDR在外汇储备中的占比,中国做了两件事情:
推动IMF在2009年对SDR做了一次大规模增发,使其发行量一次性扩大10倍左右。要求增缴份额。使其在IMF份额从3.996%升至 6.394%,投票权随之增加。其SDR allocation在将来也会随之同比扩大。要求把RMB纳入SDR的货币篮子当中 第一条,不需要美国国会批准。而对于后两点,美国是极力反对的。所以这件事情从2010年被提出,一直拖到了2015年底,才终于在美国国会批准。可以说,不是IMF批准人民币“入篮”SDR,而是美国国会批准了此事。因为美国对IMF具有绝对的控制权,它在IMF中有权否决一切提议。
截至2016年6月30日,中国央行的外汇储备资产中包括:3万亿的外汇储备、800亿的货币黄金和100亿的SDR。可见SDR的地位可忽略不计,更何况SDR的流动性远远不能和美国国债相比。
有观点说,SDR作为一种外汇储备资产,可被列入IMF 100多个成员国的资产负债表上。而RMB作为SDR的…