在调试C代码时处理不明确的结构声明

时间:2018-06-04 08:35:05

标签: c debugging pdb-files one-definition-rule proj

我目前正在调试osgeo / proj.4中某个坐标投影算法的代码,将其与我怀疑存在错误的另一个实现进行比较。

proj.4包含多个具有相同名称的结构的不同声明,每个声明都在一个单独的.c文件中:

struct pj_opaque {
    double phic0;
    double cosc0, sinc0;
    double R2;
    void *en;
};

struct pj_opaque {
    double K, c, hlf_e, kR, cosp0, sinp0;
};

(以及更多)。 我感兴趣的正确结构声明:

struct pj_opaque {
    double  A, B, E, AB, ArB, BrA, rB, singam, cosgam, sinrot, cosrot;
    double  v_pole_n, v_pole_s, u_0;
    int no_rot;
};

这似乎会导致调试器出现问题。在运行时,我无法查看我感兴趣的结构的所有值,因为调试器使用了类型的不兼容声明,该声明没有我想要查看的成员

这是一个例子: Q的类型为pj_opaque *,我想查看成员u_0。在观察中,struct Q甚至没有成员u_0。通过Q-> u_0直接访问它会产生错误。 (班级" XYZ"没有会员" UVW")

Visual Studio debugger/watch uses wrong struct declaration

在调试时是否有一种通用的方法来处理这种歧义,比如编译器开关,这会使这些模糊的名称变得独一无二?

对于记录:proj.4是在Windows上使用vcpkg构建的,调试器是Visual Studio 2017。

1 个答案:

答案 0 :(得分:1)

我猜测问题是来自调用者,结构声明是不透明的,所以你无法看到它,无论其他地方是否有一个或几个结构定义。这意味着调用者只有一个不完整的声明,例如某处typedef struct pj_opaque pj_opaque。这意味着调用者无法知道该结构的内容,这是一种在C中进行OO和私有封装的方法。

明智的做法是:

// top of caller .c file
#ifdef DEBUG_RELEASE
struct pj_opaque { /* definition here */ };
#endif

这允许调用者.c文件的编译器知道结构包含什么,将其传递给目标文件,而目标文件又可以传递给调试器文件格式。这有点脏,因为它只是在调试模式下将代码暴露给调用者。更漂亮的替代方法是创建一个头文件,如“pj_opaque_debug.h”,您可以在其中放置上面的编译器开关代码。