问题
Although "Undefined Reference error" questions have been asked several times, I couldn't find solution to my problem.
I am trying to get flex and bison to work in a Qt app. I am facing problem in linking only.
These are the relevant files-
1) icd.l - Lex specification - It generates iclexer.c and contains definition of functions-
void yyerror(char const *s){...}
void* setUpBuffer(char const* text){...}
void tearDownBuffer(void* buffer){...}
int nextToken(){...}
2) iclexer.h
#ifndef ICLEXER_H
#define ICLEXER_H
extern void yyerror(char const *);
extern int yylex();
extern char* yytext;
extern void* setUpBuffer(char const* text);
extern void tearDownBuffer(void* buffer);
extern int nextToken();
#endif // ICLEXER_H
3) icparser.h
#ifndef ICPARSER_H
#define ICPARSER_H
#include "iclexer.h"
#include <string>
extern void initLexer(std::string const& t);
extern void clearLexer();
extern int yyparse();
class Parser
{
public:
Parser(std::string const& s)
{
initLexer(s);
}
void parse()
{
yyparse();
}
~Parser()
{
clearLexer();
}
};
#endif // ICPARSER_H
4) icd.y - Bison specification - It generates icparser.cpp and contains definition of functions-
void initLexer(std::string const& t);
void clearLexer();
int yylex();
In my GUI code I include icparser.h and use class Parser
's interface. But I am getting following error-
/home/vinayak/codes/qt/dic_sim/icparser.cpp:1402:
error: undefined reference to `yyerror(char const*)'
And similar errors for setUpBuffer(char const* text);
, tearDownBuffer(void* buffer);
and nextToken();
. Basically the functions in iclexer.c are not getting linked properly.
Please tell me how to either modify this code or how to change linking order in Qt (Qt Creator)?
回答1:
If the generated header file is exactly as stated, i.e. without any extern "C"
then the problem you might be facing is that the C compiler will generate an unmangled symbol when compiling the function, but the C++ compiler will generate a dependency to the mangled name. The linker will see the dependency and the symbol, but not having the same name it will fail to match them together.
Take a look at the documentation of the tool used to generate the code and find how to generate C++ compatible code (usually just requires the inclusion of extra extern "C"
code in the headers).
回答2:
Concerning your error: undefined reference to 'yyerror(char const*)'
, you might want to read the Bison documentation, and more specifically the part about yyerror. It reads:
— Method on parser: void error (const location_type& l, const std::string& m)
The definition for this member function must be supplied by the user: the parser
uses it to report a parser error occurring at l, described by m.
This definition is probably missing in your code. Note that yyerror
is actually yy::parser::error
, with yy::
the parser's default namespace (which can be changed with %define namespace "foo"
)and parser::
the parser class's name by default (which can be changed with %define parser_class_name foo
).
Your other errors seem unrelated to Bison.
Edit: oh, you seem to be generating C parsers, not C++ parsers. Well, it's the same for C parsers: yyerror is user-supplied.
The following definition suffices in simple programs:
void
yyerror (char const *s)
{
fprintf (stderr, "%s\n", s);
}
来源:https://stackoverflow.com/questions/14482338/undefined-reference-error-even-though-the-functions-are-present