【问题标题】:Multiple definitions?多重定义?
【发布时间】:2015-03-03 04:49:42
【问题描述】:

我在编译我的 flex 和 bison 代码时遇到了问题。更具体地说是我的 parser.yy 文件。在这个文件中,我包含了 MathCalc.h 和 BaseProg.h,它们是我创建的类。问题是当我实例化类时,它在编译时给了我一个“多重定义”错误。任何帮助,将不胜感激!谢谢!!

Parser.yy (sn-p):

%code requires {
#include <iostream>
#include <cmath>
#include "MathCalc.h"
#include "BaseProg.h"
/* Parser error reporting routine */
void yyerror(const char *msg);

/* Scannar routine defined by Flex */
int yylex();

using namespace std;
BaseProg bprog;
MathCalc calc;

enum Type { INT, FLT};
}
/* yylval union type */
%union {
        double dval;
        int ival;
        char* name;
        Type type;
}

错误:

bison -d parser.yy
g++    -c -o scanner.o scanner.cc
g++    -c -o parser.tab.o parser.tab.cc
g++ scanner.o parser.tab.o BaseProg.o MathCalc.o -lfl -o ../Proj2
parser.tab.o:(.bss+0x0): multiple definition of `bprog'
scanner.o:(.bss+0x28): first defined here
parser.tab.o:(.bss+0x1): multiple definition of `calc'
scanner.o:(.bss+0x29): first defined here
collect2: ld returned 1 exit status

【问题讨论】:

  • 仅供参考,“flex”标签指的是 Apache Flex。对于您的问题,“flex-lexer”标签是合适的。

标签: c++ parsing bison yacc flex-lexer


【解决方案1】:

%code requires 块中的任何代码都将放置在解析器源文件和解析器头文件中。在scanner源码中解析器头文件#include是正常的(毕竟这就是bison生成头文件的原因),所以将全局变量定义放在%code requires块中是不明智的。

确实,将全局变量定义放在头文件中总是不明智的,正是因为头文件可能包含在多个源文件中,结果任何全局定义(与声明相反)都会插入多个翻译单元,违反 ODR。

对于头文件,您应该将这些对象(BaseProg bprog;MathCalc calc;)标记为extern,然后确保您确实在某个源文件中定义了它们。或者,更好的是,您应该首先避免使用全局变量。

【讨论】:

  • 谢谢!这真的解决了问题!我对它有了更好的理解!
猜你喜欢
  • 2021-12-14
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 2014-09-06
  • 2011-06-25
  • 2014-03-25
  • 1970-01-01
相关资源
最近更新 更多