随笔-90  评论-947  文章-0  trackbacks-0

嗯,写篇文章的目的是为了把我最新(现在是次新)的那篇文章给刷下去——我不想每次看见它了。

不知大家有没有发现,当使用 VS 来调试代码的时候,那些 STL 容器的信息会以比较看得懂的方式显示出来:

image

 

而我们自己写的,它只能按照数据成员来显示,如果数据结构稍微复杂点,看这些直接显示的内容得到的有用信息就会很少了:

image

 

那么,是否有办法能让 IDE 按照我们设想的方式来显示数据呢?答案是肯定的。这个配置就位于 autoexp.txt 中(具体路径为 X:\Program Files\Microsoft Visual Studio 10.0\Common7\Packages\Debugger\autoexp.dat,如果是 VS 不同版本,“Microsoft Visual Studio 10.0”中的版本号换成其他的即可,VS 2005 以上版本都支持)。

在里面搜索 vector,可以找到作用于 vector 的调试信息显示方式的语句:

std::vector<*>{
    preview (
        #(
            "[",
            $e._Mylast - $e._Myfirst,
            "](",
            #array(
                expr: $e._Myfirst[$i],
                size: $e._Mylast - $e._Myfirst
            ),
            ")"
        )
    )

    children (
        #(
            #([size] : $e._Mylast - $e._Myfirst),
            #([capacity] : $e._Myend - $e._Myfirst),
            #array(
                expr: $e._Myfirst[$i],
                size: $e._Mylast - $e._Myfirst
            )
        )
    )
}

这个语法的详细官方说明好像没有,不过大体上可以猜出来。

第一行 std::vector<*> 是类型,说明下面的内容针对 std::vector,并且适用于任意模版参数。紧接着是一个大括号括起来的段落。

preview 开始的那一段表示当该变量单行显示的时候该如何显示,也就是下图第二列的样子:
image

IDE 会依次显示 preview(#( … )) 括号内的以逗号分隔的内容,加引号的会原样显示,变量用 $e 引用(将 $e 视为该类型的一个变量)。

除了直接引号,变量的运算结果外,这里还可以写一些高级点的玩意儿,如 #array,#list,#tree。

#array 的格式为:
#array(
    expr: … ,
    size:  …
)
其中 expr 里可以使用 $i,$i 为元素 index,size 表示元素个数。最终的结果为:
$i=0时的expr, $i=1时的expr, …, $i=size时的expr。

假设有一个结构:
struct Vector
{
    int *pData;
    int nCount;
};
其中 p 是指向一块 count 个 int 的内存。如果要依次显示这 count 个数字,preview 中应该写:
preview (
    #(
        #array(
            expr: $e.pData[$i],
            size: $e.nCount
        )
    )
)

#list 的格式为:
#list(
    head: … ,
    size: … ,
    next: …
) : …
其中 head 是指向第一个 Node 的指针,size 表示元素个数,next 表示 Node 中指向下一个 Node 的分量名,最后冒号后面还要写一个 Node 中的值分量,也就是要显示的那个变量。

假设有结构:
struct ListNode
{
    int nData;
    ListNode *pNext;
};
struct List
{
    ListNode *pHead;
    int nCount;
};
preview 的写法为:
preview (
    #(
        #list(
            head: $e.pHead,
            size: $e.nCount,
            next: pNext
        ) : $e.nData    // 注意,这里的 $e 代表 ListNode,上面两个 $e 都代表 List
    )
)

#tree的格式为
#tree(
    head: …,
    left: …,
    right: …,
    size: …
) : …
其中 head 是指向根节点的指针,left 和 right 分别是指向左右子树的分量名,size 表示元素个数,最后冒号后面写节点中的值分量。IDE会对整棵树做中序遍历。

假设有结构:
struct TreeNode
{
    int nData;
    TreeNode *pLeft;
    TreeNode *pRight;
};
struct Tree
{
    TreeNode *pRoot;
    int nCount;
};
preview 的写法为:
preview (
    #(
    #tree(
        head: $e.pRoot,
        left: pLeft,
        right: Right,
        size: $e.nCount
        ) : $e.nData // 注意,这里的 $e 代表 TreeNode,上面两个 $e 都代表 Tree
    )
)


preview 的格式就到此。接下来是 children,它用于描述点击变量左边的加号后,展开的内容怎么显示,如图:

image

IDE 会依次显示 children(#( … )) 括号内的以逗号分隔的内容,每个显示为一行。刚才的 #array, #list, #tree 都可以用,会显示成第一列索引第二列值的样子。
另外可以用 #(first, second) 的格式,first 会原样显示在第一列,second 会求值显示在第二列。

 

了解以上这些内容,我们已经可以针对 STL 的那些数据结构做自定义显示了,对一些别的数据结构作简单的自定义显示也不难。

 

最后给个效果图,定义了我自己的那些容器的显示方式。怎么样,看上去一定比开头给出的那个冷冰冰的样子好很多吧?

image

posted on 2011-02-27 17:10 溪流 阅读(11965) 评论(22)  编辑 收藏 引用 所属分类: C++

评论:
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-02-27 18:29 | expter
我热,我以为是VS对战平台;:)。。。
哦,学习下先:)  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-02-27 21:50 | OwnWaterloo
学习鸟!!!  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-02-28 01:24 | 陈梓瀚(vczh)
@OwnWaterloo
微软一个叫STL的人在redmond开过这个讲座的,就是说怎么在autoexp里面搞自己的东西。  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-02-28 09:03 | ooseven
学习了,感谢分享!  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-02-28 09:40 | 空明流转
@陈梓瀚(vczh)
我想知道GDB里面怎么配置这个玩意儿。  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-02-28 13:14 | zwp
学习,MARK~
  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-02-28 16:02 | OwnWaterloo
@陈梓瀚(vczh)
这人的名字真诡异……
BTW, 微软内部使用VS是怎么算的? 也需要"购买"什么的么?
会被强制使用最新版本么? 2010?  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-02-28 16:04 | OwnWaterloo
@空明流转
gdb不一定有这个功能, 而且也不应该有这个功能吧?
从VC6不支持来看, 也应该是IDE实现的而不是windbg。

只要有耐心, emacs应该是可以实现的。  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 00:59 | 陈梓瀚(vczh)
@OwnWaterloo
装在公司里面的VS当然是不购买的。强制的话很简单,我checkin一个新版本的工程文件,全组人都得装新的。  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 01:12 | OwnWaterloo
@陈梓瀚(vczh)
貌似08和05的sln格式区别就只有第1行?

其实我是觉得08很慢, 比05慢。
据用过10同学说, 10更慢……
如果公司要强制推行自家的新产品就有点过分了……

如果只是开发C/C++, 不涉及.net和html什么的, 08、10完全没优势?
如果要用C++0x, 可以用单独的cl16, IDE还是用05……
我就只下了cl16, 没有VS10的IDE……
  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 01:14 | 溪流
@OwnWaterloo
在足够牛b的机器上,不见得新版本比旧版本慢啊  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 01:23 | OwnWaterloo
@溪流
在足够牛b的机器上 eclipse netbeans也不慢, 你用吗~  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 01:30 | 溪流
@OwnWaterloo
如果好用我就用呀~  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 01:34 | OwnWaterloo
@溪流
对于编辑C/C++来说, 除了慢, 没发现08比05有什么新功能……
对于发布来说, 发布一个VC6的dsw, 用户只要不低于VC6, 他就能编译。
高版本的IDE有从低版本工程文件导入的功能, 反之没有……  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 10:45 | 陈梓瀚(vczh)
@OwnWaterloo
你觉得我们能换软件,就不能换硬件吗?  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 10:46 | 陈梓瀚(vczh)
@OwnWaterloo
那你就只能把自己的代码写成适应vc6的bug的形式了  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 14:37 | OwnWaterloo
@陈梓瀚(vczh)
硬件当然再进步, 可以换更快的。
但这和更新软件是两码事。

有更快的硬件, 不是"我们就应该用更消耗硬件资源软件"的理由吧?  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 14:38 | OwnWaterloo
@陈梓瀚(vczh)
vc6确实对C++确实有点过分了。
那改成如果发布C++, 用VC8的sln, VC9,10都可以编译。
如果发布C, 那用VC6的dsw, VC6,8,9,10都可以编译。
  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-01 17:27 | 陈昱(CY)
2008只知道用那个查看类图的功能,2010目前还不知道  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-02 11:46 | 陈梓瀚(vczh)
@OwnWaterloo
如果软件不更加占用资源,硬件基本没什么动力发展……  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-02 12:40 | 陈梓瀚(vczh)
@OwnWaterloo
不过我觉得一个软件要干更多的事情,肯定要更加消耗CPU的。我觉得“要求他们拼了命改算法”是得不偿失的,如果从收益上看的话。  回复  更多评论
  
# re: 一个好玩的玩意儿:VS 的 autoexp.txt 2011-03-14 18:45 | Soli
确实很好玩。。。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理