I am still using BDS2006 (Turbo explorer C++) and upgrading is still not an option. I have a problem that while debugging some of more advanced template/classes containing properties like:
__declspec( property (get=???, put=???) ) ??? ???;
are handled as member variables making the watch list and debugger going nuts if there are too many of them. The result is big slow down during breakpoints and traces and occasional (very often) freezing of the IDE itself when such class is in the watch list (with the only remedy to use windows task manager to end bds.exe
process tree).
SO my question is:
Q1: How to hide these properties so they are not visible in watch list while they still remain public
?
I think there might be some kind of macro or directive for this. Making those not public
is not an option. The watch list handles this properties like member variables instead of functions.
Here small example (extracted vec2
class from my GLSL math):
//---------------------------------------------------------------------------
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
//---------------------------------------------------------------------------
usage:
vec2 a;
a=vec2(0.1,0.2);
a+=a; // <<- here breakpoint
Watch list:
[+]a { { 0.1, 0.2 }, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ... }
if I open the [+]
sub-menu of a
watch it displays:
[-]a { { 0.1, 0.2 }, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ... }
[+]dat {0.1,0.2}
so no more properties... which might hint the watch list window might be somehow configurable to achieve this with some hidden option too.
This small single class instance is not a big problem but when I change to something like this:
vec2 a[20];
a[0]=vec2(0.1,0.2);
a[1]=a[0]; // <<- here breakpoint
and watching a
again the IDE froze instantly on the breakpoint and only Kill process is my next possible step. Now imagine bigger project where there are much more classes and dynamic lists of those ... Such project is non possible to debug properly (or at all) anymore.
PS. the freezing of IDE in BDS2006 is a well known bug. If the watch list is showing too much data (it can be just a long string nothing fancy) the IDE slows down and freeze (according of how much data is displayed and how many steps F7/F8 are done).
Edit1:
As a workaround I added configuration macros that disable most of the swizzling for Apps that does not need it. Here a watch list screenshot example for a simple class:
But there is a lot of stuff that needs the swizzling and even simple stuff like this is already stretching the limits of the watch window.
Edit2: progress update
None of the #pragma statements looks promising. From 2010 the Debugger_Visualizers has been added to the IDE which could solve this however I am still on older version and porting is not an option for now.
current workaround for arrays:
vec2 a[20];
a[0]=vec2(0.1,0.2);
a[1]=a[0]; // <<- here breakpoint
watch:
| 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 } |
so for singular instances use vec2::dat
member instead of vec2
. For arrays using array watch format a[start index].dat,number of items
instead of a
.
This is fast (does not freeze) however its potentionaly access violating due to hard-coded size (which must be hardcoded number no expressions or variables). This still can not be used for whole struct/classes
that are more complex (like polygons,meshes) but at least now there is some debugging option for arrays.