1

我仍在使用 BDS2006(Turbo explorer C++)并且升级仍然不是一个选项。我有一个问题,在调试一些包含以下属性的更高级的模板/类时:

__declspec( property (get=???, put=???) ) ??? ???;

被作为成员变量处理,如果监视列表和调试器太多,它们就会发疯。结果是在断点和跟踪期间大大减慢,并且当此类在监视列表中时,IDE 本身偶尔(经常)冻结(唯一的补救措施是使用 Windows 任务管理器来结束进程树)。bds.exe

所以我的问题是:

Q1:如何隐藏这些属性,使它们在观察列表中不可见,而它们仍然存在public

我认为可能有某种宏或指令。使那些不是public不是一种选择。监视列表像处理成员变量而不是函数一样处理此属性。

这里的小例子(vec2从我的 GLSL 数学中提取的类):

//---------------------------------------------------------------------------
template <class T> class _vec2
    {
public:
    T dat[2];
    _vec2(T _x,T _y) { x=_x; y=_y; }
    _vec2() { for (int i=0;i<2;i++) dat[i]=0; }
    _vec2(const _vec2& a) { *this=a; }
    ~_vec2() {}
    // 1D
    T get_x() { return dat[0]; } void set_x(T q) { dat[0]=q; }
    T get_y() { return dat[1]; } void set_y(T q) { dat[1]=q; }
    __declspec( property (get=get_x, put=set_x) ) T x;
    __declspec( property (get=get_y, put=set_y) ) T y;
    __declspec( property (get=get_x, put=set_x) ) T r;
    __declspec( property (get=get_y, put=set_y) ) T g;
    __declspec( property (get=get_x, put=set_x) ) T s;
    __declspec( property (get=get_y, put=set_y) ) T t;

    // 2D
    _vec2<T> get_xy() { return _vec2<T>(x,y); } void set_xy(_vec2<T> q) { x=q.x; y=q.y; }
    _vec2<T> get_yx() { return _vec2<T>(y,x); } void set_yx(_vec2<T> q) { y=q.x; x=q.y; }
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> xy;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> xg;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> xt;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> yx;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> yr;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> ys;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> ry;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> rg;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> rt;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> gx;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> gr;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> gs;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> sy;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> sg;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> st;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> tx;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> tr;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> ts;

    // operators
    _vec2* operator = (const _vec2 &a) { for (int i=0;i<2;i++) dat[i]=a.dat[i]; return this; }                              // =a
    T& operator [](const int i)     { return dat[i]; }                                                                      // a[i]
    _vec2<T> operator + ()          { return *this; }                                                                       // +a
    _vec2<T> operator - ()          { _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=      -dat[i];           return q; } // -a
    _vec2<T> operator ++ ()         {                   for (int i=0;i<2;i++)                 dat[i]++;     return *this; } // ++a
    _vec2<T> operator -- ()         {                   for (int i=0;i<2;i++)                 dat[i]--;     return *this; } // --a
    _vec2<T> operator ++ (int)      { _vec2<T> q=*this; for (int i=0;i<2;i++)                 dat[i]++;         return q; } // a++
    _vec2<T> operator -- (int)      { _vec2<T> q=*this; for (int i=0;i<2;i++)                 dat[i]--;         return q; } // a--

    _vec2<T> operator + (_vec2<T>&v){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=       dat[i]+v.dat[i];  return q; } // a+b
    _vec2<T> operator - (_vec2<T>&v){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=       dat[i]-v.dat[i];  return q; } // a-b
    _vec2<T> operator * (_vec2<T>&v){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=       dat[i]*v.dat[i];  return q; } // a*b
    _vec2<T> operator / (_vec2<T>&v){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=divide(dat[i],v.dat[i]); return q; } // a/b

    _vec2<T> operator + (const T &c){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=dat[i]+c;                return q; } // a+c
    _vec2<T> operator - (const T &c){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=dat[i]-c;                return q; } // a-c
    _vec2<T> operator * (const T &c){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=dat[i]*c;                return q; } // a*c
    _vec2<T> operator / (const T &c){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=divide(dat[i],c);        return q; } // a/c

    _vec2<T> operator +=(_vec2<T>&v){ this[0]=this[0]+v; return *this; };
    _vec2<T> operator -=(_vec2<T>&v){ this[0]=this[0]-v; return *this; };
    _vec2<T> operator *=(_vec2<T>&v){ this[0]=this[0]*v; return *this; };
    _vec2<T> operator /=(_vec2<T>&v){ this[0]=this[0]/v; return *this; };

    _vec2<T> operator +=(const T &c){ this[0]=this[0]+c; return *this; };
    _vec2<T> operator -=(const T &c){ this[0]=this[0]-c; return *this; };
    _vec2<T> operator *=(const T &c){ this[0]=this[0]*c; return *this; };
    _vec2<T> operator /=(const T &c){ this[0]=this[0]/c; return *this; };
    // members
    int length() { return 2; }  // dimensions
    };
//---------------------------------------------------------------------------
template <class T> T min(const T &a,const T &b)  { if (a<b) return a; return b; }
template <class T> T max(const T &a,const T &b)  { if (a>b) return a; return b; }
double abs(const double &a) { if (a<0.0) return -a; return a; }
//---------------------------------------------------------------------------
// get vector size
template <class T> double   length   (const _vec2<T> &v)  { double l=0.0; for (int i=0;i<2;i++) l+=v.dat[i]*v.dat[i]; return sqrt(l); }
// get vector size^2
template <class T> double   length2  (const _vec2<T> &v)  { double l=0.0; for (int i=0;i<2;i++) l+=v.dat[i]*v.dat[i]; return l; }
// get unit vector
template <class T> _vec2<T> normalize(const _vec2<T> &v)  { _vec2<T> q=v; double l=divide(1.0,length(v)); for (int i=0;i<2;i++) q.dat[i]*=l; return q; }
// get dot product
template <class T>       T  dot  (const _vec2<T> &v1,const _vec2<T> &v2) { T l=0.0; for (int i=0;i<2;i++) l+=v1.dat[i]*v2.dat[i]; return l; }
// c+v
template <class T> _vec2<T> operator + (double c,_vec2<T>&v){ _vec2<T> q; for (int i=0;i<2;i++) q.dat[i]=c+v.dat[i];  return q; }
// c-v
template <class T> _vec2<T> operator - (double c,_vec2<T>&v){ _vec2<T> q; for (int i=0;i<2;i++) q.dat[i]=c-v.dat[i];  return q; }
// c*v
template <class T> _vec2<T> operator * (double c,_vec2<T>&v){ _vec2<T> q; for (int i=0;i<2;i++) q.dat[i]=c*v.dat[i];  return q; }
//---------------------------------------------------------------------------
typedef _vec2<float >  vec2;
typedef _vec2<double> dvec2;
typedef _vec2<bool  > bvec2;
typedef _vec2<int   > ivec2;
typedef _vec2<DWORD > uvec2;
//---------------------------------------------------------------------------
vec2 GLSL_math_test2;   // ensure that template code is compiled/linked
//---------------------------------------------------------------------------

用法:

vec2 a;
a=vec2(0.1,0.2);
a+=a;         // <<- here breakpoint

观察名单:

[+]a    { { 0.1, 0.2 }, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ... }

如果我打开手表的[+]子菜单,它会显示:a

[-]a    { { 0.1, 0.2 }, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ... }
  [+]dat {0.1,0.2}

所以没有更多的属性......这可能暗示监视列表窗口可能以某种方式配置以通过一些隐藏选项来实现这一点。

这个小的单类实例不是一个大问题,但是当我改为这样的时候:

vec2 a[20];
a[0]=vec2(0.1,0.2);
a[1]=a[0]; // <<- here breakpoint

并再次观察aIDE 在断点处立即冻结,只有 Kill 进程是我的下一个可能步骤。现在想象更大的项目,其中有更多的类和动态列表......这样的项目不再可能正确(或根本)调试。

PS。BDS2006 中IDE 的冻结是一个众所周知的错误。如果监视列表显示太多数据(它可能只是一个长字符串,没什么花哨的),IDE 会减慢并冻结(根据显示的数据量和 F7/F8 执行的步骤数)。

编辑1:

作为一种解决方法,我添加了配置宏来禁用不需要它的应用程序的大部分调配。这是一个简单类的监视列表屏幕截图示例:

观察名单

但是有很多东西需要调配,甚至像这样简单的东西已经超出了观察窗口的极限。

Edit2:进度更新

#pragma声明中没有一个看起来很有希望。从 2010 年开始,Debugger_Visualizers已添加到 IDE 中,这可以解决这个问题,但是我仍在使用旧版本,目前移植不是一个选项。

数组的当前解决方法:

vec2 a[20];
a[0]=vec2(0.1,0.2);
a[1]=a[0]; // <<- here breakpoint

手表:

| a[0].dat,20 | { 0.1, 0.2 }, { 0.1, 0.2 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } |

因此,对于单个实例,请使用vec2::datmember 而不是vec2. 对于使用数组监视格式 a[start index].dat,number of items而不是a.

这很快(不会冻结),但是由于硬编码的大小(必须是硬编码的数字,没有表达式或变量),它可能会违反访问权限。这仍然不能用于struct/classes更复杂的整体(如多边形、网格),但至少现在有一些用于数组的调试选项。

4

2 回答 2

1

当您想改变对象在调试环境中的可视化方式时,您可以尝试使用本机可视化器。我愿意给你一些信息,但看到这个主题的大小,也许你在决定是否使用这项技术之前首先想先看看。

于 2020-07-07T12:03:48.877 回答
0

您可以通过在监视窗口中单击鼠标右键并取消选中任何变量前面的复选框来禁用监视表达式/变量。这将从调试器中禁用它们,但它们仍将保留在监视窗口中。

您还可以“分组”监视表达式/变量,然后启用/禁用组中的所有监视以打开/关闭监视值的显示 - 这可以提高调试器的速度。

http://docwiki.embarcadero.com/RADStudio/Sydney/en/Watch_List_Window

禁用手表

禁用监视表达式,以便在您单步执行或运行程序时不会对其进行监视。手表设置保持定义。禁用手表可以提高调试器的性能。

您还可以决定要包含哪些符号表以进行调试 - 查看

http://docwiki.embarcadero.com/RADStudio/Sydney/en/Debugger_Symbol_Tables

于 2020-07-06T17:58:22.167 回答