Flex生成的lex.yy.c链接外部函数ast_add_child时出现未定义引用错误
SQL解析器链接错误问题解决
你的问题并非Flex生成文件链接的常见问题,核心原因是C与C++混合编译的名字修饰不兼容:
- Flex生成的
lex.yy.c是C代码,你用gcc编译它;但你的AST实现是C文件(Ast.cpp)。C编译器会对函数名进行名字修饰(比如ast_add_child会被编译成类似_Z12ast_add_childP9AstNodeS_的符号),而C代码中调用的是未修饰的原始函数名,链接器无法找到匹配的符号,因此报"未定义引用"错误。
两种可行解决方案
方案一:统一用C++编译所有代码
既然AST模块是C++实现,直接用g++编译所有文件,包括Flex生成的C代码:
lex SQLSelectParser.l g++ -g -c lex.yy.c -o lex.yy.o g++ -g -c Ast.cpp -o Ast.o g++ -g lex.yy.o Ast.o -o exe -lfl
方案二:为C代码提供C兼容的接口
如果要保留C代码的编译方式,需要修改Ast.h,用extern "C"包裹被C代码调用的函数声明,让C++编译器以C的规则生成函数符号:
#ifdef __cplusplus extern "C" { #endif // 声明需要被C代码调用的函数 void ast_add_child(AstNode *parent, AstNode *child); #ifdef __cplusplus } #endif
修改后,无论用gcc还是g++编译Ast.cpp,都会生成C兼容的函数符号,C代码就能正常链接。
额外验证点
- 确认
Ast.cpp中ast_add_child的实现与Ast.h中的声明完全匹配(函数名、参数类型、返回值都一致),无拼写错误。 - 链接时确保所有依赖的目标文件都被正确传入命令行。
内容的提问来源于stack exchange,提问作者Abhishek Sagar
相关产品推荐
相关产品推荐

