memory FILE in C

阅读更多关于《memory FILE in C》

一直希望有个可以像 FILE* 一样使用的 memory file,正好,今天,在linux的stdio.h中找到了这个东西。

 

#define _GNU_SOURCE
#include <
stdio.h>

FILE *fmemopen(void *buf, size_t size, const char *mode);

FILE *open_memstream(char ** ptr, size_t *sizeloc) ;

 

详细说明:http://linux.die.net/man/3/open_memstream

 

fmemopen 有用之处主要在于从内存中读取,使用 fscanf。当然也可以写,如果是为了写,并且随后再读,可以将 buf 和 size指定为 NULL,0,这样写时会自动增加内存。

 

open_memstream 就主要用于写了,比如生成sql语句:

 

张功耀:比毒乃分危害更大的是毒中药

阅读更多关于《张功耀:比毒乃分危害更大的是毒中药》

张功耀:比毒乃分危害更大的是毒中药

张功耀 中南大学教授

最近被揭露出来的毒乃分事件,不是一个孤立的事件。它是公蝉档即将革皮的标志,也是对我国腐朽的医药文化根深蒂固,不断沉渣泛起,使我们中国长时期地对于食品和药品的安全问题麻木不仁的一种报答。

事实上,在我们中国,还有一种比毒奶粉危害更大的东西,那就是毒中药。

xxx、潲水油、吊块、毒奶粉,这样一些东西,因为可能涉及到每一个中国(享受特供待遇的除外),所以,它能够激起差不多每一个中国的义愤。由于现在吃中药的已经不多,加之一些别有用心的至今还在为中药毒害做掩盖、粉饰和辩护,所以,对毒奶粉恨之入骨的未必会对毒中药有相同的觉悟。

为什么说毒中药是一种更严重的毒害呢?

一、毒中药害是以有意或无意两种方式进行的。

明明那中药都已经陈化、变质、发霉、虫蛀了,中医骗子一句“越陈越好”的话就可以轻而易举地把所有陈药卖掉。这种欺骗本属于“有意的欺骗”。可是,我国那些愚昧得可爱的,在理直气壮地接受“越陈越好”的歪理邪说之后,不但不对这种“有意的欺骗”恨之入骨,而且还会对它感恩戴德,山呼万岁。

中药毒害的更大一部分源自“无意的欺骗”。

熟悉中医的知道,中医的医和药都没有实验基础。它是用“意”来决定“医”的,即所谓“医者意也”。

医生的“意”来自两个方面:

一是通过观察附会得到的“意”。孙思邈在《千金方》当中告诉读者,把蛇蜕用一个绢带装好,扎在孕妇的腰上,就可以防止孕妇横生逆产。这其中的“意”就来自对“蛇能够蜕皮”的观察。把这个蛇蜕皮的“意”附会到孕妇生产上,就形成了用蛇蜕预防孕妇难产的“医”。附会到眼睛里边的翳,就形成了用蛇蜕除翳的“医”。南宋的时候,江浙一带的农民学会了养蚕。医生发现蚕虫也蜕皮。于是,蚕蜕也被用来治疗妇女难产和为眼睛除翳了。再后来,医生发现母孵小的时候,那小居然可以破壳而出,把这个“破壳而出”的“意”附会到妇女难产,母孵小时留下的鸡蛋壳也用来为妇女催产。有人说,中医是“唯物主义”,读者可以判断一下,这种“医者意也”的中医哲学究竟唯物到了什么程度?

中医形成“意”的第二个源头是《黄帝内经》之类的文化垃圾。中医推荐患者吃和喝尿,其“理论依据”就来自这本混账透顶的《黄帝内经》。

据《本草纲目》记载,“”(也就是)可以用五种不同的方法入药。医生通常用它来治疗咳嗽、食积、劳极骨蒸、噎食不下、心腹急痛、解疔疮肿毒,等等。

中医推荐患者吃的这个医术,其“意”是怎样形成的呢?

《黄帝内经·素问》第五篇《阴阳应象大论》说:“清阳出上窍,浊阴出下窍;清阳发腠理,浊阴走五脏;清阳实四肢,浊阴归六腑。”这里的“上窍”,就是指耳、目、口、鼻头部七窍;“下窍”就是指的前后二阴。这里的“清阳”,是指“上窍”发出的声音,和经由耳、鼻、口腔出入的各种气。“浊阴”也就是大便和小便。由于最后修改《黄帝内经》的混蛋王冰,说了“清阳发腠理,浊阴走五脏;清阳实四肢,浊阴归六腑”,食古不化的中医后生,就从这里得出一个推论:既然浊阴是“走五脏”“归六腑”的东西,“”()和“轮回”(尿)可以入药,也就变得“理直气壮”了!

只要能够形成“意”,就可以采取与这个“意”对应的“医”,既不需要做任何有效性实验,更不要做任何安全性实验,不管三七二十一地“先吃两付药试试”,这就是所谓的“中医”。由于被医生治疗过的病人,没有被当场毒死,甚至还有不少中医医术与某些疾病的自愈性相偶合了,“治愈”了不少病人,于是,麻木而愚顽的中医信徒就这样造就出来了。

由于医生是依据他们想当然的“意”来决定“医”的,所以,每一个医生在采取某种医术的时候都十分盲目。这就导致了医生无意地先将别人毒死,然后又无意地将自己也毒死的荒唐故事。2006年8月,河北省行唐县龙岗卫生院的阎山川老中医,先无意地将郝淑琴毒死,后为了“证明自己的清白和自己行医几十年的医术”,用同样的中药将自己也毒死,就是这样的一个典型案例。

注:原文以被当山掉了,所以拷贝过来

vim –cmd "set fileencoding=utf-8"

阅读更多关于《vim –cmd "set fileencoding=utf-8"》

在很多时候,这个fileencoding无法发挥作用:

在windows上,用notepad将一个文本文件 test.txt 存储为unicode16或unicode16be

然后:vim –cmd “set fileencoding=utf-16” test.txt

它还是乱码,用 :set fileecoding 显示是 cp936

但是:vim –cmd “set fileencoding=utf-16”

不提供文件名,:set fileecoding 显示正确,是 utf-16

 

vim –help 提示:

   –cmd <command>      加载任何 vimrc 文件前执行 <command>

 

说明 fileencoding 是在某个 vimrc 中被修改了,这个“聪明的”vimrc 非常聪明地将fileencoding修改了

不过我好想没找到那个可以再执行完 vimrc 再执行命令的选项。

 

——————————————————————————

找到了一个办法,在 .vimrc 中,把fileencodings【注意,是复数】那行改成:

set fileencodings=utf-bom,UTF-8,UTF-16BE,UTF-16,g18030,big5,euc-jp,euc-kr,iso8859-1

因为utf,前四个,都是非常严格的编码,而 fileencodings 是需要把严格的编码放在最前的,因为它一旦尝试到一种成功的编码之后就不再继续尝试(没有做概率分析,看哪种编码最合适)。

有个插件,用概率分析判断编码:http://www.vim.org/scripts/script.php?script_id=1708

 

函数调用太快了

阅读更多关于《函数调用太快了》

在至强服务器上,使用 febird/vcproj/test_trb 测试 trb。结果发现使用compare函数指针的find仅比直接比较快17%!我原本以为至少要快一倍,因为在Windows(PentiumM Dual Core)上,直接比较的版本要快80%左右。

经过测试,发现:现代Cpu的流水线真强!

 

运行时间显示(单位是纳秒):

服务器(至强四核 2.29G): [doit=4971:  3.952, null=1648:  1.310, pse=4327:  3.440]

台式机(奔腾双核 2.49G): [doit=6585:  5.301, null=1679:  1.352, pse=2246:  1.808]

 

doit表示pf_compare的那个循环

null表示那个啥也没干(volatile 用来禁止编译器优化)

pse表示那个累加循环

 

虽然主频低,但是服务器明显要快得多(不然至强怎么比奔腾贵那么多?)。

 

我看过pc下vc 2008 生成的代码,累加的那个循环,其中循环体26条指令(包含跳转指令)。平均每次循环仅消耗约4.5个时钟周期!流水线、分支预测这么强,在包含跳转的情况下,每个时钟周期还能执行3~4条指令!

更可怕的,在服务器上,一个包含函数调用的循环,仅需要9个时钟周期(2.29*3.95=9.05)!这完全颠覆了我对现代CPU的世界观。

 

这个简单的测试也说明,为什么find函数的compare_fun_ptr版本这么快(比较两个整数的函数是非常trivial的)。

完整的测试代码在:http://code.google.com/p/febird

在其中:$febird_home/vcproj/test_trb

 

函数指针之间的比较

阅读更多关于《函数指针之间的比较》

因为某种原因(Threaded Red black tree C++ warpper),需要比较两个函数指针是否相等。但是,这么貌似很简单的需求却得不到满足。

下表,是在Visual C++ 2008 中,同一个函数通过不同途径得到的指针

key_comp

0x0041158c _febird_trb_compare_less

febird::G_relocate_febird_trb_compare_less

0x101cb4a4 _febird_trb_compare_less

febird_trb_compare_less

0x1051af60 febird_trb_compare_less(const trb_vtab *, const void *, const void *)

 

函数 febird_trb_compare_less 在 febird.dll 动态库中,并且导出。


febird::G_relocate_febird_trb_compare_less 是在 febird.dll 中定义了一个全局函数指针变量,并初始化为 &febird_trb_compare_less 。

key_comp 是使用 febird.dll 并将 &febird_trb_compare_less 传递给febird.dll中的另一个函数(假设函数名为foo)。以上三个不同的指针值就是在foo中查看到的。

 

在网上搜索了很多关于函数指针比较的东西,最终得出的结论是:跨越dll的函数指针比较是未定义的,除非是其中一个是NULL指针。不光vc,很多其他编译器也做不到跨dll的已定义的函数指针比较。

原本以为是dll重定位的问题,但是将函数指针放到 febird::G_relocate_febird_trb_compare_less 中也无济于事,反而更多出了一个指针值(0x101cb4a4 )。

 

最终我的问题也解决了,就是在把这个比较放在头文件中,并且,key_comp作为一个模板参数来直接和&febird_trb_compare_less比较。

 

另外,函数指针作为模板参数时,不能将NULL之类的东西作为该模板参数传递。因为这个时候模板参数必须是一个const extern变量。如果试图传递NULL,在不同的编译器下会得到不同的错误信息(这样做在GCC4.1下编译过了,但连接错误)。

 

骂人的最高境界

阅读更多关于《骂人的最高境界》

这个世界上奇人真不少:

http://www.tianya.cn/publicforum/content/feeling/1/931833.shtml