我正在使用一个C ++库,它提供了一个对象,为了简单起见,它或多或少是这样的:
class ExampleSO {
public double* narray;
};
我有一个ExampleSO
的实例,其narray
大约为200.其他方法ExampleSO::method()
使用此数组执行许多算术函数并将其分配给不同的数组元素:
ExampleSO::method() {
// a lot of operations
narray[50] = narray[1] * narray[2] / narray[40];
// and so on
此代码由另一个程序生成,它使用一堆定义来处理数组元素,因此代码如下所示:
#define A narray[0]
#define X narray[1]
#define Y narray[2]
// ...
#define Z narray[40]
// ....
#define U narray[50]
// ... more, until narray[199]
ExampleSO::method() {
// a lot of operations
U = X * Y / Z;
// and so on
}
我的问题是,最终一些数组元素是NaN,我正在尝试调试代码以查看原因。我已经发现了其中的一些,主要是由零除,其他通过非常小的数字(在0和+/- 0.1之间的小数)引起。
由于我对gdb魔法知之甚少,我设法通过display *(this->narray) @ 200
看到数组元素,但是这个数组非常大,因此不可读。
所以调试这段代码已经变成了一个简单的任务,因为#defines
隐藏了元素的位置,数组太大了,因为很多元素变成了NaN,我迷失了
我的问题是:您有什么想法/建议来帮助我调试此代码?当第一个数组元素变成NaN时,条件断点可能有用吗?我怎么能用这样的结构呢?
谢谢!
答案 0 :(得分:4)
narray[12]
p printMyFavoriteValues(narray)
#ifdef DARWIN
_mm_setcsr( _MM_MASK_MASK &~
(_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO) );
#else
feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);
#endif
答案 1 :(得分:1)
关于定义,您可以通过预处理器运行文件,然后编译和调试预处理文件本身。
X,Y,Z宏将以这种方式解析,你会看到实际的索引。如何调用预处理器本身取决于您的编译器。对于gcc,它是cpp命令Documentation。
关于找出分配NaN的时间,应该有一个编译器开关,当程序发生这种情况时会使程序抛出异常。
答案 2 :(得分:0)
如果需要调试宏调用生成的大量代码而无法重构删除宏,则可以选择暂时预处理文件,复制宏生成的代码并将其粘贴到宏上调用。然后,您就可以编译已经预处理的代码并正确调试。当你完成后只需恢复代码。