KEEP K.I.S.S.

tk's blog

中秋

你那么憎恨军人,跟他们斗了那么久,琢磨了他们那么久,最终却变得和他们一样。人世间没有任何理想值得以这样的沉沦作为代价。 —— 《百年孤独》

沉寂了5个月了,再不写点什么,会让人以为我已经不在了呢?

这5个月过的实在不算是好吧,目前仍然处在泥泞的情绪沼泽里。

这段时间接触的东西也有一些,暂时没有深入。

  1. TexMacs. 可以说是 Amazing 的格式文档工具,尤其是输入公式的时候。结构化的文档排版很直观,特别适合我这种不会 LaTeX 的。推荐在 linux 下使用。

  2. 重新学学 Scheme,准备好好读读《SICP》

  3. 读书。读完了《万里任禅遊》《百年孤独》也读了一半了。两本书都强烈推荐。

有时间要写写 Scheme 和 TexMacs 的笔记。

无题

又是许久没有更新博客了,五一期间回了趟家,在家真是各种舒服,比起一直在下雨的广州,(。ŏ_ŏ)

近来的感觉是越来越碎片化了,精力觉得无法集中,兴趣程度也是堪忧的状态,工作呢,代码是在写,但是觉得并不是很用心。

想的是多了点,把生活中的复杂性过度抽取到自己的想法里了,思绪总是纷杂,╮(╯-╰)╭,静不下心。

慢慢自解。

 

 

[翻译] Keep your vimrc file clean

 

英文原文: Keep your vimrc file clean.
作者: Datagrok
翻译: tisyang


本站和其他一些网站所写的关于 Vim 的技巧都会让你在 .vimrc 文件中添加某些代码。(在 Windows 平台,对应的是 _vimrc 文件。)参阅 :help vimrc-intro

当你添加多次之后,.vimrc 文件会变得相当大并且复杂,尤其是你添加的那些分别针对特定语言的配置。更糟糕的是,一些设置有可能互不兼容。

幸运的是,Vim 有一个良好的内建机制去组织管理针对特定语言的配置,将它们分置在不同的文件和目录。完整资料请参考 help vimfiles, :help ftplugin-overrule, :help after-directory

快捷方法就是将全部针对特定语言的配置从你的 .vimrc 文件中移到一个名为 .vim/ftplugin/language.vim 的文件中。(在 Windows 上对应的是 $HOME/vimfiles/ftplugin/language.vim

比如本来的 .vimrc 文件是这样:

autocmd FileType * set tabstop=2|set shiftwidth=2|set noexpandtab
autocmd FileType python set tabstop=4|set shiftwidth=4|set expandtab
au BufEnter *.py set ai sw=4 ts=4 sta et fo=croql

移动之后变成这样,针对 python 的配置移动到了一个单独的文件中:

" File ~/.vimrc
" ($HOME/_vimrc on Windows)
" Global settings for all files (but may be overridden in ftplugin).
set tabstop=2
set shiftwidth=2
set noexpandtab

" File ~/.vim/ftplugin/python.vim
" ($HOME/vimfiles/ftplugin/python.vim on Windows)
" Python specific settings.
setlocal tabstop=4
setlocal shiftwidth=4
setlocal expandtab
setlocal autoindent
setlocal smarttab
setlocal formatoptions=croql

如果你想完全禁用某个随 Vim 发行的文件类型的插件时,首先建立你自己的文件类型配置文件(也许是空的),然后添加一行代码:

let b:did_ftplugin = 1

如果你觉得 Vim 自带的某个文件类型的插件大多数功能都不错,只是想改写某些特定的配置项时,你可以将你的配置放到 .vim/after/ftplugin/language.vim (在 Windows 上对应的是 $HOME/vimfiles/after/ftplugin/language.vim )详见 :help after-directory

如果你想让 Vim 识别一个新的扩展名文件,不要在你的 .vimrc 文件中使用 augroup 。将你的配置放到正确的位置。详见 :help ftdetect

关于 ~/.vim 目录(Windows 上的 $HOME/vimfiles )你可以做的更多。目录 ~/.vim/compiler 是一个存放应用到每个编译器基础之上的配置的好地方(比如说,我也许需要使用 javac, jikes, ant 或者 make 去编译然后解析编译器针对对一个 java 源文件的输出。) 【原文: ~/.vim/compiler is a good place to keep configuration that gets applied on a per-compiler basis(for example, I might need to use any of javac, jikes, ant, or make to compile and parse the compiler output for a java source file.) 】 我也喜欢将一些 color schemes 存放在 ~/.vim/colors, 用 Vim 帮助文件的格式记笔记存放在 ~/.vim/doc 。定期运行 :helptags ~/.vim/doc 命令可以让我在这些笔记里使用 :h 跳转到指定标签。 详见 :help helptags :help vimfiles

这个技巧建议将针对特定语言的配置移到一个适当的 ftplugin file 中。如果想让它生效,你需要启用文件类型检测功能。输入命令 :filetype 来检测文件类型检测是否已经启用。在某些 Linux 发行版中,文件类型检测被禁用,这时你需要添加如下的命令到你的 vimrc 文件中:

filetype plugin on
" Alternative: use the following to also enable language-dependent indenting.
filetype plugin indent on

类型转换及 Type Punning

 

将一个 float 类型的值转换为网络字节序,该如何做?

除了手动编码转换外,我们知道 htonl 是将一个32bit无符号整数转换为网络字节序,而 float 也是32bit,那么只要能将一个 float 类型的值转换为bit位相同的 uint32 值,之后再同样转换回 float 就应该可以了。

一般我们会想到利用指针强制类型转换来迫使编译器重新解释指针指向的内存:

float hton_f(float value)
{
    int tmp = htonl(*(unsigned int *)&value);
    return *(float *)&tmp;
}

指针存储的是内存中的地址,地址上的内容由指针类型来解释。这种强制类型转换的技巧叫做 Type punning . 事实上,这种方法存在隐患。

Type punning
A form of pointer aliasing where two pointers and refer to the same location in memory but represent that location as different types. The compiler will treat both "puns" as unrelated pointers. Type punning has the potential to cause dependency problems for any data accessed through both pointers.

多数时候,Type punning 并不会引起任何问题。虽然在 C 标准中它属于依赖实现的实现,但通常可以正常工作。[参考*]

当打开 GCC 的编译选项 -fstrict_aliasing (优化选项 -O2 等会默认打开这个选项)时,则有可能出现问题。编译器认定两种不同类型(signed/unsigned不影响,还有 char *void * 是例外)的指针不会指向同一内存地址,它们之间也没有依赖关系,这种认定下编译器可以对程序进行优化,比如会将不同类型的指针进行操作的代码的顺序(编译的机器码)打乱。而如果这两种类型指针事实上指向同一位置,那么程序代码的执行结果可能会出乎意料(执行顺序跟代码中的顺序不一致)。这种规则也称之为 strict aliasing rule .

一个可以使用的解决方法是使用 union 来进行转换:

float hton_f(float value)
{
    union tagFTOI { 
        float f;
        unsigned int i;
    };
    ((union tagFTOI *)&value)->i = htonl(((union tagFTOI *)&value)->i);               
    return ((union tagFTOI *)&value)->f;
}

除了这种指针写法外,还可以用值方法,就是临时定义一个 union 对象,然后进行赋值转换。

根据 C 标准,任何使用 type punning 的行为依赖编译器实现。那么根据“标准”来看,使用 union 也不是一定能解决问题。标准中规定,设置了 union 中的某个域的值,那么就应该在相同的域读回。

但是大多数编译器都支持使用 union 来进行 type punning 而不破坏 strict aliasing rule . 比如 GCC,GCC 文档中写道:

The practice of reading from a different union member than the one most recently written to (called “type-punning”) is common. Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type.

strict aliasing rule 有两个例外,char *void * 指针,举个栗子,用代码实现 float 的绝对值函数:[来源*]

float funky_float_abs (float *a)
{
    float temp_float = *a;
    // valid, because it's a char pointer. These are special.
    unsigned char * temp = (unsigned char *) a;
    temp[3] &= 0x7f;
    return temp_float;
}

float funky_float_abs (float *a)
{
    int temp_int i;
    float temp_float result;
    // Memcpy takes void pointers, so it will force aliasing as well.
    memcpy (&i, a, sizeof (int));
    i &= 0x7fffffff;
    memcpy (&result, &i, sizeof (int));
    return result;
}

上面两个函数都可以正常工作而不违反 strict aliasing rule 规则。至于函数怎么实现 float 的绝对值,可以参考 float 通常是如何在计算机上存储的。


参考资料

  1. Type punning.
  2. Type punning isn't funny: Using pointers to recast in C is bad.
  3. "What are the common undefined/unspecified behavior for C that you run into?.
  4. Type-punning and strict-aliasing

Google Reader

 

 

寻找Google Reader的替代

作者:

Google无情砍掉了一个备受人喜欢的产品。Google Reader是一个受重度阅读用户欢迎的专业Web阅读器,它本来有一个活跃的分享社区,但Google先是强行用Google+替代了Buzz,现在则是彻底抛弃了Google Reader。多家网站迅速发表文章列出Google Reader的替代,如CNET和Lifehacker,而Feedly则宣布要克隆Google Reader。也许我们能找到功能类似的阅读器,但我们曾经倾注的心血则付之东流,永远不会再回来,已关闭的博客存档,被审查的文章副本,在其它地方还能轻松的找到吗?

-------------------------------------------------------------------------------------

说什么好呢