My MSN

Click OK to add this content

 
Content Preview: rss
-+is_integral 宏展开
216 days ago
struct integral_c_tag {     static const int value = 0; }; template< bool C_ > struct bool_ {     static const bool value = C_;     typedef integral_c_tag tag;     typedef bool_ type;     typedef bool value_type;     operator bool() const     {         return this->value;     } }; typedef bool_<true> true_; typedef bool_<false> false_; template< typename T, T N > struct integral_c; template <class T, T val> struct integral_constant: public integral_c<T, val> {     typedef integral_constant<T,val> type; }; template<> struct integral_constant<bool,false>: false_ {    typedef integral_constant<bool,false> type; }; template<> struct integral_constant<bool,true>: true_ {     typedef integral_constant<bool,true> type; }; template< typename T > struct is_integral : integral_constant<bool,false>    { }; template<> struct is_integral<unsigned char> : ...
-+_beginthread还是CreateThread
251 days ago
http://www.diybl.com/  _beginthread还是CreateThread 发表于 2006-01-28 01:56 AM 作者: polyrandom 程序员对于Windows程序中应该用_beginthread还是CreateThread来创建线程,一直有所争论。本文将从对CRT源代码出发探讨这个问题。 I. 起因 今天一个朋友问我程序中究竟应该使用_beginthread还是CreateThread,并且告诉我如果使用不当可能会有内存泄漏。其实我过去对这个问题也是一知半解,为了对朋友负责,专门翻阅了一下VC的运行库(CRT)源代码,终于找到了答案。 II. CRT CRT(C/C++ Runtime Library)是支持C/C++运行的一系列函数和代码的总称。虽然没有一个很精确的定义,但是可以知道,你的main就是它负责调用的,你平时调用的诸如strlen、strtok、time、atoi之类的函数也是它提供的。我们以Microsoft Visual.NET 2003中所附带的CRT为例。假设你的.NET 2003安装在C:\Program Files\Microsoft Visual Studio .NET 2003中,那么CRT的源代码就在C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\crt\src中。既然有了这些实现的源代码,我们就可以找到一切解释了。 III. _beginthread/_endthread 这个函数究竟做了什么呢?它的代码在thread.c中。阅读代码,可以看到它最终也是通过CreateThread来创建线程的,主要区别在于,它先分配了一个_tiddata,并且调用了_initptd来初始化这个分配了的指针。而这个指针最后会被传递到CRT的线程包装函数 _threadstart中,在那里会把这个指针作为一个TLS(Thread Local Storage)保存起来。然后_threadstart会调用我们传入的线程函数,并且在那个函数退出后调用_endthread。这里也可以看到, ...
-+tokenizer 使用例子
257 days ago
#include<iostream> #include <boost/tokenizer.hpp> #include<string> int main() {     using namespace std;     using namespace boost;     string s = "12252001";     int offsets[] = {1,2,3,4};     offset_separator f(offsets, offsets+4);     typedef token_iterator_generator<offset_separator>::type Iter;     Iter beg = make_token_iterator<string>(s.begin(),s.end(),f);     Iter end = make_token_iterator<string>(s.end(),s.end(),f);     // 上面这行语句也可以这样写:     // Iter end;       for(;beg!=end;++beg)     {         cout << *beg << "\n";       } string str = "just test;;Hello world -foo--bar;yow;baz "; typedef tokenizer<char_separator<char> > token; char_separator<char> sep(" -; "); token tokens(str, sep);    for (token::iterator tok_iter = tokens.begin();     tok_iter != tokens.end(); ++tok_iter) {     cout << "<" << *tok_iter << "> "; } ...
-+如何编写异常安全的C++代码
263 days ago
http://tech.163.com 2006-04-17 09:19:59 来源: 网易学院(广州)  网友评论0 条 论坛 关于C++中异常的争论何其多也,但往往是一些不合事实的误解。异常曾经是一个难以用好的语言特性,幸运的是,随着C++社区经验的积累,今天我们已经有足够的知识轻松编写异常安全的代码了,而且编写异常安全的代码一般也不会对性能造成影响。   使用异常还是返回错误码?这是个争论不休的话题。大家一定听说过这样的说法:只有在真正异常的时候,才使用异常。那什么是“真正异常的时候”?在回答这个问题以前,让我们先看一看程序设计中的不变式原理。   对象就是属性聚合加方法,如何判定一个对象的属性聚合是不是处于逻辑上正确的状态呢?这可以通过一系列的断言,最后下一个结论说:这个对象的属性聚合逻辑上是正确的或者是有问题的。这些断言就是衡量对象属性聚合对错的不变式。   我们通常在函数调用中,实施不变式的检查。不变式分为三类:前条件,后条件和不变式。前条件是指在函数调用之前,必须满足的逻辑条件,后条件是函数调用后必须满足的逻辑条件,不变式则是整个函数执行中都必须满足的条件。在我们的讨论中,不变式既是前条件又是后条件。前条件是必须满足的,如果不满足,那就是程序逻辑错误,后条件则不一定。现在,我们可以用不变式来严格定义异常状况了:满足前条件,但是无法满足后条件,即为异常状况。当且仅当发生异常状况时,才抛出异常。   关于何时抛出异常的回答中,并不排斥返回值报告错误,而且这两者是正交的。然而,从我们经验上来说,完全可以在这两者中加以选择,这又是为什么呢?事实上,当我们做出这种选择时,必然意味着接口语意的改变,在不改变接口的情况下,其实是无法选择的(试试看,用返回值处理构造函数中的错误)。通过不变式区别出正常和异常状况,还可以更好地提炼接口。   对于异常安全的评定,可分为三个级别:基本保证、强保证和不会失败。   基本保证:确保出现异常时程序(对象)处于未知但有效的状态。所谓有效,即对象的不变式检查全部通过。   强保证:确保操作的事务性,要么成功,程序处于目标状态,要么不发生改变。   不会失败:对于大多数函数来说,这是很难保证的。对于C++程序,至少析构函数、释放函数和swap函数要确保不会失败,这是编写异常安全代码的基础。 ...
-+使用dbghelp获取调用堆栈--release下的调试方法学
263 days ago
Author : Kevin Lynx 当软件作为release模式被发布给用户时,当程序崩溃时我们很难去查找原因。常见的手法是输出LOG文件,根据LOG文件分析 程序崩溃时的运行情况。我们可以通过SEH来捕获程序错误,然后输出一些有用的信息作为我们分析错误的资料。一般我们需要 输出的信息包括:系统信息、CPU寄存器信息、堆栈信息、调用堆栈等。而调用堆栈则是最有用的部分,它可以直接帮我们定位 到程序崩溃时所处的位置(在何处崩溃)。(codeproject上关于这个专题的常见开场白 = =#) 要获取call stack(所谓的调用堆栈),就需要查看(unwind)stack的内容。We could conceivably attempt to unwind the stack ourselves using inline assembly. But stack frames can be organized in different ways, depending on compiler optimizations and calling conventions, so it could become complicated to do it that way.(摘自vld文档)要获取栈的 内容,我们可以自己使用内联汇编获取,但是考虑到兼容性,内联汇编并不是一个好的解决方案。我们可以使用微软的dbghelp 中的StackWalk64来获取栈的内容。 StackWalk64声明如下: BOOL StackWalk64(   DWORD MachineType,   HANDLE hProcess,   HANDLE hThread,   LPSTACKFRAME64 StackFrame,   PVOID ContextRecord,   PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,   PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,   PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,   PTRANSLATE_ADDRESS_ROUTINE64 ...
© 2009 MicrosoftMicrosoft