C11标准

C11标准是C语言标准的第三版(2011年由ISO/IEC发布),前一个标准版本是C99标准。相比C99,C11有哪些变化呢——

1、 对齐处理

alignof(T)返回T的对齐方式,aligned_alloc()以指定字节和对齐方式分配内存,头文件<stdalign.h>定义了这些内容。

2、 _Noreturn

_Noreturn是个函数修饰符,位置在函数返回类型的前面,声明函数无返回值,有点类似于gcc的attribute((noreturn)),后者在声明语句尾部。

3、 _Generic

_Generic支持轻量级范型编程,可以把一组具有不同类型而却有相同功能的函数抽象为一个接口。

4、 _Static_assert()

_Static_assert(),静态断言,在编译时刻进行,断言表达式必须是在编译时期可以计算的表达式,而普通的assert()在运行时刻断言。

5、安全版本的几个函数

gets_s()取代了gets(),原因是后者这个I/O函数的实际缓冲区大小不确定,以至于发生常见的缓冲区溢出攻击,类似的函数还有其它的。

6、 fopen()新模式

fopen()增加了新的创建、打开模式“x”,在文件锁中比较常用。

7、 匿名结构体、联合体。

8、 多线程

头文件<threads.h>定义了创建和管理线程的函数,新的存储类修饰符_Thread_local限定了变量不能在多线程之间共享。

9、 _Atomic类型修饰符和头文件<stdatomic.h>。

10、改进的Unicode支持和头文件<uchar.h>。

11、quick_exit()

又一种终止程序的方式,当exit()失败时用以终止程序。

12、复数宏,浮点数宏。

13、time.h新增timespec结构体,时间单位为纳秒,原来的timeval结构体时间单位为毫秒。

Source: xundaoinfo

Tinyscheme的一个bug

    之前从1.3甚至更早开始,就发现tinyscheme运行yinyang pluzzle的时候,是有bug的。
(let* ((yin
((lambda (cc) (display #@) cc) (call-with-current-continuation (lambda (c) c))))
(yang
((lambda (cc) (display #*) cc) (call-with-current-continuation (lambda (c) c)))))
(yin yang))
本来是一个无限的过程,但是很快就结束了。
但因为本来只是业余玩这个,加上之前觉得找这种bug工作量比较大,一直没找。后来觉得这么小的scheme解释器实在是少,而且恰好有时间,还是解决了这个bug比较好。
于是去年下功夫找了下,改了这个bug。后来事情多了,又把修改的地方丢一边去了,但是还好修改过的版本一直放在网盘。
今天对比了下,找到当时改掉的bug。
是因为里面使用的将list顺序翻转的函数有2个,其中一个用起来有bug。
/* reverse list -- produce new list */
static pointer reverse(scheme *sc, pointer a) {
/* a must be checked by gc */
pointer p = sc->NIL;
for (; is_pair(a); a = cdr(a)) {
p = cons(sc, car(a), p);
}
return (p);
}
/* reverse list --- in-place */
static pointer reverse_in_place(scheme *sc, pointer term, pointer list) {
pointer p = list, result = term, q;
while (p != sc->NIL) {
q = cdr(p);
cdr(p) = result;
result = p;
p = q;
}
return (result);
}
前面的reverse会生成新的list,后面的reverse_in_place则不会。将几个使用reverse_in_place的地方改成reverse就好了。

Source: xundaoinfo

nginx配置里的一个坑

最近用flight写了点东西,因为用的request_url,所以直接用index.php框架会提示404。
用了nginx的rewrite之后,首页是没问题了,但是其他页面就都是nginx提示file not foound.rewrite配置如下
if ( !-e $request_filename ){
rewrite .* index.php last;
}
fastcgi是这么配置的
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
分明rewrite到index.php下了。找了很久,查资料都没找到原因。于是猜测是不是$fastcgi_script_name的缘故,改成
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
发现ok了。。。

前面处理的时候,发现日志已经500多m了。于是打算压缩之后删掉。直接压缩但是发现log会变,于是打算mv之后压缩,发现mv了仍然在往里写日志,原路径没生成新的日志。
一想就明白了,因为文件node的缘故。。。有时候在目录里,另外的终端删除之后重建,然后发现之前的终端里ls是没有新的文件,只有cd ..然后重新进入目录才会看到文件,也是一样的道理。

Source: xundaoinfo

php6和php7性能对比

昨天看到一个php7新特性的pdf,今天看到php.net上有php7的snapshot for win下载,于是下了一个试试。

开始用字符串和类实例化调用魔术方法试了下,php7性能是php6.6的3倍。后来看到 链接的一个测试,里面和其他语言比较,php性能垫底了。然后此处对比5.3和5.4 ,虽然有强化,但是还是很弱。下了他的测试代码,是一个找质数的,基本就是纯数字运算。测试完,发现PHP7的JIT果然不是盖的。贴下测试代码和结果吧。。。

D:devtest>D:devphp7php -v
PHP 7.0.0-dev (cli) (built: Apr 24 2015 15:06:00)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0-dev, Copyright (c) 1998-2015 Zend Technologies
D:devtest>D:devphpphp -v
PHP 5.6.6 (cli) (built: Feb 18 2015 16:02:19)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
D:devtest>D:devphpphp test.php
Test1 total cost:0.033001899719238
Test2 total cost:0.12400698661804
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Test3 total cost:63.071608066559
D:devtest>D:devphp7php test.php
Test1 total cost:0.010000944137573
Test2 total cost:0.04600191116333
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Test3 total cost:12.118693113327

其中php6.6使用内存500+m,而php7使用内存180+m。。。差别实在是非常大,这说明了JIT对于数字运算的性能提升是非常明显的,远超其他操作,就如基本操作提升大于实际项目表现一样。另外说明了php7里对解释器内存使用的优化效果也是很明显的。开始php6.6默认的内存上限120M总是不够用,会报错。

下面贴测试代码:

<?php
ini_set("memory_limit", 512*1024*1024);
$start = microtime(true);
$string = "";
for($i=0;$i < 100000;++$i){
$string .= "{$i}";
}
$end = microtime(true);
echo "Test1 total cost:".($end-$start)."n";
/**
* 
*/
class TestClass 
{
function __construct()
{
# code...
}
function __call($name,$args){
if($name == "ttt"){return 1+1;}
}
}
$start = microtime(true);
for($i=0;$i < 100000;++$i){
$obj = new TestClass();
$obj->ttt();
}
$end = microtime(true);
echo "Test2 total cost:".($end-$start)."n";
error_reporting(E_ALL);
ini_set('display_errors', '1');
function get_primes7($n) {
if ($n < 2) return array();
if ($n == 2) return array(2);
$s = range(3, $n, 2);
$mroot = sqrt($n);
$half = count($s);
$i = 0;
$m = 3;
while ($m <= $mroot) {
if ($s[$i]) {
$j = (int)(($m*$m - 3) / 2);
$s[$j] = 0;
while ($j < $half) {
$s[$j] = 0;
$j += $m;
}
}
$i = $i + 1;
$m = 2*$i + 3;
}
$res = array(2);
foreach ($s as $v) {
if ($v) {
$res[] = $v;
}
}
return $res;
}
$res = array();
$start = microtime(true);
for ($i = 1; $i <= 10; ++$i) {
$res = get_primes7(10000000);
print "Found ".count($res)." prime numbers.n";
}
$end = microtime(true);
echo "Test3 total cost:".($end-$start)."n";

Source: xundaoinfo

关于目录权限的问题

今天配置nginx+php,发现404,但路径确定没错。心想是权限的问题。但是web文件夹设置为777了都照样404。于是strace了一下,发现确实是权限问题,但不知道为啥。经人提示换了个地方,就可以访问了,但nginx对静态文件又是类似问题。才发现应该是目录的x权限的问题。x对目录是访问目录的权限。

Source: xundaoinfo

ubuntu下wifi硬件开关自动关闭

刚装好ubuntu 14.10 kylin的时候,发现wifi硬件开关未开,fn+f2也没用。各种尝试下,发现按完fn+f2后再按fn+f1睡眠起来之后就好了。
今天打算解决这个问题,找了一会,发现也有遇到相同问题的。有个在知乎问了,说没查到其他的,然后知乎上有回答的。按照他的回答,发现没用。
后来又搜到一个,看来是因为华硕的笔记本的原因。原来只要按fn+f1就够了。要解决问题可以参考这个链接
测试成功,但是貌似还是不能自动连接。

Source: xundaoinfo

whitespace解释器实现

最近学习rust,想到写什么东西练练手。简单的都写过了,web相关的库不成熟,就连std::io都在alpha后变过几次了。只能选取不涉及io的,用到容器的来试试。想到了之前一直没实现的whitespace的解释器。这东西看起来有点复杂,我用php写了个原型,原本想做成lexer和parser的。实际写的时候,发现其命令其实很简单,只是只用了LF,space,Tab,所以需要排列来构造唯一的序列。其实设计还不错,本以为还会有a命令是b命令子串的情况。结果并没有这种情况。lexer还有点用,但是parser基本没用,开始还麻烦构造语法树,后来发现这个其实就是一种低级类似汇编级别的语言,根本不需要语法树,直接翻译就好了。
php实现解释之后,觉得这种翻译成二进制由vm执行也不错。结果用c写了个vm。写着写着发现,如果不是ws的字符有点怪,翻译成pop,push这种,其实就是一种虚拟机上的opcode。于是查了下虚拟机相关内容。用c实现了一个简单的,这次opcode由自己设计。
whitespace实现中,除了开始一些处理和调试外,后来明显没错误了,但是执行结果老是和他官方对不上。后来研究了一个实现,(ws资料和实现都非常少),发现算数操作和比较都需要把堆栈上的top元素pop出来,而我开始没pop。还有要注意的是输入输出的时候,stack存的是heap上的地址。

官网
wiki
项目

rust的pointer和borrowing

对于rust的pointer和borrowing,前面没理解明白,以为是指针在函数调用过程中的传值。但是在学习和写代码的过程中,发现一些问题,传指针老是提示类型不匹配。仔细找了些资料,现在rust的资料很少,中文的就更少,而且rust前期变化太快,也不一定适用。
找到一个2014年的文章http://segmentfault.com/blog/xiongxin/1190000000596516 说到一些问题,之前传值的时候函数参数用的&mut xx:T,如果是xx:&T或者xx:&mut T,要么有类型问题,要么不能修改变量的值。原来是传参数的时候需要使用&mut x这样显式地说明是可写指针。这样好处是指针的使用更明确不容易出错,而且编译器更容易跟踪,避免指针上出问题。 不过这个&到处加都没报错,不知道都是什么含义。

use std::vec::Vec;
fn test1(mut n: i32){
n = 8;
}
fn test2( n: &mut i32){
*n = 8;
}
//fn test3(n: &i32){
//  *n = 8;
//}
fn main(){
let mut t:i32= 1;
t = 2;
println!("raw-t:{}",t);
test1(t);
println!("test1-t:{}",t);
let mut t2:i32 = 2;
test2(&mut t2);
println!("test2-t2:{}",t2);
//let t1 = 1;
//test3(&t1);
//println!("test3-t1:{}",t1);
}

Source: xundaoinfo

折腾ubuntu 14.10硬盘安装

笔记本上的win7越来越卡,加上最近本来就没什么空,游戏玩得少,学习的多,这样就想和之前一样弄个双系统。
现在用的大部分是easyBCD,用了下,确实很方便,但是直接用iso的那个项无法启动。打算用上面的grub试试,grub参数有点变化。启动的时候总是提示找不到cdrom,手动mount不支持ntfs。在grub指定了下iso,发现还是提示找不到cdrom。然后换了debian,也是一样。改成arch,提示找不到cdrom,但是手动mount可以挂载。但挂载了也无法安装,后来又找到一个将iso加载到内存的方法。http://blog.sina.cn/dpool/blog/s/blog_6c9d65a10100oetc.html 用debian成功,试了下ubuntu,也是成功了。
然后分区提示不能卸载iso所在分区,但是根本没涉及这个分区啊,只是写了分区表。结果我退出去用shell分好之后,再试,也是不行。后来看到前面那个链接里写了这个问题。。。然后安装成功。
进入系统,装了点东西后,发现用账号登不进去了。切换到tty1,又建了个用户,发现还是不行。开始以为是输入法的问题,但观察发现和密码错误不太一样。于是找了下,有说是窗口管理器的问题,我之前也遇到过换成xfce就可以的情况,但发现不登录不能打开wifi,guest虽然能进,但是也没法打开wifi,也没法修改设置。。。tty1改/etc/profile等也没用,最后发现http://tieba.baidu.com/p/3333869633 然后登进去了。
发现现在unity和应用中心都和苹果越来越像了。。。

Source: xundaoinfo

PHP 7.0性能与php5.6对比

之前看到phpng已经进入php的git主线。编译github上的phpng,编译很顺利,结果发现运行有问题。最近在家用git.php.net上的最新代码又编译了一次,貌似没问题。到公司也下了个,多了个commit,然后编译执行文件也没问题。测试了下性能。
第一个简单的调用函数测试:

function add($a ,$b){
return $a + $b;
}
$t=microtime(true);    
for(   $i=0;$i <1000000;$i++) {     
if(($i%20)!=0)    
{  
add($i , $i+1);
}     
else     
{  
add($i-1 , $i);
}     
}  
$t1 = microtime(true);
echo   "costs: ";   echo   $t1-$t;   echo   " n";   

php -v
PHP 5.6.3 (cli) (built: Nov 12 2014 17:19:25)
Copyright (c) 1997-2014 The PHP Group

php test.php
costs: 0.20501208305359

php -v
PHP 7.0.0-dev (cli) (built: Jan 19 2015 16:44:35)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0-dev, Copyright (c) 1998-2015 Zend Technologies

php test.php
costs: 0.15400910377502

$primes = [];
function isPrime($a){
global $primes;
foreach($primes as $b){
if($a %  $b == 0 ){
return false;
}
}
return true;
}
$t=microtime(true);    
for(   $i=2;$i <100000;$i++) {     
if(isPrime($i)){
array_push($primes, $i);
} 
}  
$t1 = microtime(true);
echo   "costs: ";   echo   $t1-$t;   echo   " n";   

php 7

php test.php
costs: 2.0501170158386

php 5.6

php test.php
costs: 1.9711117744446

再换一段 来源

error_reporting(E_ALL);
ini_set('display_errors', '1');
function get_primes7($n) {
if ($n < 2) return array();
if ($n == 2) return array(2);
$s = range(3, $n, 2);
$mroot = sqrt($n);
$half = count($s);
$i = 0;
$m = 3;
while ($m <= $mroot) {
if ($s[$i]) {
$j = (int)(($m*$m - 3) / 2);
$s[$j] = 0;
while ($j < $half) {
$s[$j] = 0;
$j += $m;
}
}
$i = $i + 1;
$m = 2*$i + 3;
}
$res = array(2);
foreach ($s as $v) {
if ($v) {
$res[] = $v;
}
}
return $res;
}
$t1 = microtime(true);
$res = array();
for ($i = 1; $i <= 10; ++$i) {
$res = get_primes7(1000000);
//print "Found ".count($res)." prime numbers.n";
}
$t2 = microtime(true);
echo "cost:" . ($t2 - $t1);

php 5.6

php test.php
cost:3.7742161750793

php7

php test.php
cost:0.85604906082153

Source: xundaoinfo