#include <iostream>
// 可以检测 int * int, int + int 等等是否溢出。 不能检测unsigned int * unsigned int 是否溢出
// ( 因为一旦超过0x7FFFFFFF则会被置溢出位,但是对于unsigned int 显然还没有溢出)
// ---------------------- over flow test 1 ------------------------
#define IF_NOT_OVERFLOW(X) __asm jo overflow##x
#define ELSEIF_OVERFLOW(X) __asm jmp overflowend##x \
__asm overflow##x:
#define END_NOT_OVERFLOW_TEST(X) __asm overflowend##x:
// ---------------------- over flow test 2 ------------------------
#define IF_OVERFLOW(X) __asm jno not_overflow##x
#define ELSEIF_NOT_OVERFLOW(X) __asm jmp not_overflowend##x \
__asm not_overflow##x:
#define END_OVERFLOW_TEST(X) __asm not_overflowend##x:
int main(int, char*[])
{
std::cout << "input x, y " << std::endl;
int x;
int y;
std::cin >> x >> y;
int m = x * y;
IF_OVERFLOW( xym);
std::cout << "over flow" << std::endl;
ELSEIF_NOT_OVERFLOW(xym);
std::cout << "m = " << m << std::endl;
END_OVERFLOW_TEST(xym);
return 0;
}

效果截图
加入了多人处理,解决了一些bug。分割背景的算法重写了,地面的问题还在处理中,呵呵。
如果在xp下,要是程序访问3GB用户内存,必须在boot.ini里打开/3GB选项。然而悲惨的是,不是所有机器在打开/3GB选项后,都能正常启动系统(具体原因未知,不过遇到过几台机都这样了)。
今天瞎碰,居然发现在64位的win7下,32位程序就可以直接使用到3GB用户内存(2011-05-27: 经测试,最高可以使用到4GB用户内存)。 当然,程序链接的时候,也同样需要打开Enable Large Address选项才能让该程序访问3GB的用户内存。
32位win7下则不行。
ps,今天程序使用了2.8GB的虚拟地址, 其中物理内存2.1GB。再大一点就得大改程序了。好险!
也算是我们team这一阶段的一个成果吧
Markless human motion capture
Get the Flash Player to see this player.
非官方非正式发布^_^
使用git-http-backend来提供git服务,可以利用apache的用户认证模块来做读写控制。然而当用户提交的时候,git仓库里记录的却是用户本地设置的user.name (使用git config user.name设置,我们接下来称之为author), 而不是apache登陆时的用户名(committer)。 这显然不合逻辑。找了很久也没有找到在推送的时候,修改author为committer的方法,只好妥协一下了:在服务器端接收到push信息的时候,进行committer和author的检查,如果相同,则允许push。否则,拒绝该次push,并提示用户committer与author不同。
解决方案自然也就是这样的:在hooks目录下建立一个pre-receive文件, 当服务器接收push的时候,pre-receive将被自动调用。
另外,git-http-backend中已经建立了一个环境变量GIT_COMMITTER_USER,正好对应committer。因此只要检查GIT_COMMITTER_USER与每个提交的author是否匹配即可。
pre-receive内容如下:
#!/bin/sh
#获取提交信息
read COMMIT_FROM COMMIT_LAST COMMIT_REFS
if [ $COMMIT_FROM = "" ]
then
echo "nothing committed?"
echo 0
fi
REV_LIST=$(git rev-list $COMMIT_FROM..$COMMIT_LAST $COMMIT_LAST --pretty=format:%an)
#echo rev-list: $COMMIT_FROM -- $COMMIT_LAST -- $REV_LIST
#分割REV_LIST,每3个字符串为一组提交,最后一个为该次提交author的名字
declare -i index=0
for AUTHOR_NAME in $REV_LIST; do
((index++))
if [ $index -eq 3 ]
then
((index=0))
#检查提交的用户名(apache用户名),与提交作者,是否是同一个人
if [ $GIT_COMMITTER_NAME = $AUTHOR_NAME ]
then
XXX=XXXX #nothing todo
#echo "committer name euqal author name, ok"
else
echo --rejected: committer:$GIT_COMMITTER_NAME doesnt match author:$AUTHOR_NAME
exit 1
fi
#AUTHOR_NAME=AUTHOR_NAME+x;
fi
done
echo "all is ok. done ^_^"
exit 0
^_^第一次写bash脚本,字符串分割还没学会,写了一个丑陋的for循环,呵呵。
刚才群里难得讨论一次编程问题,大致是子类继承基类的operator=时,无法编译通过。代码如下:
template <class T>
class Base
{
protected:
T *a;
public:
Base<T>& operator=(T *p)
{
a = p;
return *this;
}
};
class Out
{
};
class Foo : public Base<Out>
{
};
int main(int argc, char* argv[])
{
Foo foo;
Out o;
foo = &o; // 这里编译失败
return 0;
}
原因似乎是因为foo=&o这一项一定会在Foo里寻找 构造函数,或者operator=,但Foo恰恰都没有。解决方案? 修改Foo的实现为即可
class Foo : public Base<Out>
{
public:
using Base<Out>::operator=;
};
当然最好的解决方案还是删除Foo类,使用typedef定义之,代码如下:
typedef Base<Out> Foo;
Foo foo;
亦即去掉继承,直接使用模板即可。
在SSE里,要求数据是按16字节对齐的。直接使用_aligned_malloc,确实能保证对齐,只是在释放的时候,也必须配套使用_aligned_free。因此,我决定写一个基类,通过重载operator new和operator delete,自动调用_aligned_malloc和_aligned_free,一定程度上统一调用方式:使用的时候可以和普通类一样只是new/new[]和delete/delete[]即可实现自动对其的功能。
#pragma once
#include <malloc.h>
#include <new>
#include <cassert>
template< typename Base, size_t AlignmentSize>
class class_aligned_new
{
public:
static void* operator new( size_t size )
{
if( size == 0) size = 1;
void* raw = _aligned_malloc( size, AlignmentSize);
if( raw == 0) // 分配失败?
{
new_handler globalhandler = std::set_new_handler(0);
std::set_new_handler(globalhandler);
if (globalhandler) // 如果设置了new_handler,则调用它
{
(*globalhandler)();
}
else // 否则抛出异常
{
throw std::bad_alloc();
}
}
return raw;
}
static void* operator new[]( size_t size )
{
// 众多的检查,但是在release下,将会被优化掉
int base_size = sizeof( Base);
bool self_aligned = false;
if ( base_size != 0)
{
self_aligned = ( base_size % AlignmentSize == 0);
}
if( self_aligned )
{
return operator new( size);
}
else
{
// 编译器计算的长度不能符合_aligned_malloc的要求,因此抛出异常
throw std::bad_alloc();
}
}
static void operator delete( void* addr )
{
if( addr != 0) _aligned_free( addr);
}
static void operator delete[]( void* addr)
{
operator delete( addr);
}
};
使用起来和直接使用对象差不多,只是得注意new[]的时候的特殊要求。由于编译器会自动生成数组的长度,因此当Base的长度不能直接满足对其的要求时,禁止new[]
#include <iostream>
#include "aligned_class_new.h"
// 测试类,按16对齐
class test_class: public class_aligned_new< test_class, 16>
{
public:
int a;
int b;
int c;
int d;
};
int main( int argc, char* argv[])
{
test_class* tc1 = new test_class;
test_class* tc_array = new test_class[10];
delete tc1;
delete[] tc_array;
}
用起来是不是感觉和普通对象一样的呢?
很简单的问题,所以还是先看代码吧:
#include <iostream>
enum SampleEnum
{
Sample_Value_0 = 0,
Sample_Value_1 = 1
};
#define SampleMacro Sample_Value_1
int main( int argc, char* argv[])
{
int sum = 0;
#if ( SampleMacro == Sample_Value_0)
sum += 3;
#endif
#if (SampleMacro == Sample_Value_1)
sum += 7;
#endif
std::cout << sum << std::endl;
}
ok, 你会认为最终的输出的sum值是多少呢? 很遗憾,结果是10。
enum并不会在预处理阶段初始化,导致#if ( SampleMacro == Sample_Value_0) 和 #if ( SampleMacro == Sample_Value_1) 结果都成立,两段代码都被执行了。至于为何两端代码不是都不执行,这个我也说不出个所以然。
最终的解决方案是将 Sample_Value_0 和 Sample_Value_1 都写成宏定义。
另外补充一下,我的环境是vc2010