在使用 gdb 调试一些 C 代码时,我遇到了一些我以前从未见过或听说过的东西!编译器(gcc -O0)似乎创建了一种新类型,用于将向量数组传递给函数......我认为!看看下面的代码和gdb信息:
/* The Vector type - nothing unusual */
typedef struct {
float x,y,z;
} Vector;
/* The function I was debugging.
* The second parameter is what seems to have changed */
extern void gui_shader_draw(
guiShader *shader,
Vector quad[ 4 ], // << This is the one!
Vector origin,
Vector rotation,
Vector scale,
bool focus,
int mode );
我在 gui_shader_draw 函数中设置了一个断点,这就是我所看到的:
break shader.c:248
Breakpoint 1 at 0x80013ac0: file src/gui/shader.c, line 248.
(gdb) continue
Continuing.
// I have split the next line
Breakpoint 1, gui_shader_draw (
shader=0x80588ea8,
quad_t=0x80585fe8, // << What the?
origin=...,
rotation=...,
scale=...,
focus=false,
mode=3) at src/gui/shader.c:249
// The values quad_t points to are all good
(gdb) print quad_t[0]
$10 = {x = -320, y = -240, z = 0}
(gdb) print quad_t[1]
$11 = {x = 320, y = -240, z = 0}
(gdb) print quad_t[2]
$12 = {x = 320, y = 240, z = 0}
(gdb) print quad_t[3]
$13 = {x = -320, y = 240, z = 0}
quad_t 从哪里来?它肯定不是我的任何代码中的 typedef 。系统头文件 sys/types.h 有一个quad_t别名(long int),但这似乎完全不相关!这是怎么回事?我错过了一些明显的事情吗?
编辑 1:我必须指出代码可以编译并且工作正常。与其他一些名为quad_t 的变量或类型没有冲突。我只是好奇 GCC 做了什么以及为什么。
编辑2:按照建议,我查看了预处理器输出,实际上“Vectorquad[4]”的所有实例都已更改为“Vectorquad_t[4]”,因此名称已更改,而不是类型。
extern void gui_shader_draw(
guiShader *shader,
Vector quad_t[ 4 ],
Vector origin,
Vector rotation,
Vector scale,
_Bool focus,
int mode
);
预处理器输出中没有名为“quad_t”的类型定义。但我确实在 sys/types.h 中找到了这个(我之前错过了 - d'oh!)
/usr/include$ find . | xargs grep -s quad_t
./sys/types.h:typedef __uint64_t u_quad_t;
./sys/types.h:typedef __int64_t quad_t;
./sys/types.h:typedef quad_t * qaddr_t;
./sys/types.h:# define quad quad_t // << There you are!
代码中发生的事情与任何 typedef 完全无关,因为更改与任何类型完全无关。发生变化的是函数参数的name,而不是其类型,这从调试器输出中可以立即明显看出。
既然您看到预处理器输出中的变化,唯一合理的解释是代码中的某个地方有一个
#define quad quad_t
所以你必须寻找
#define
来寻找quad
,而不是quad_t
。不用说,预处理器输出中不会出现 #define
。您必须在所有包含的(直接和间接)头文件中进行全局搜索。