0

I've recreated the advanced calculator from the book "flex & bison" and made some minor adaptations for c++. But what I cannot solve is that I get following error when compiling.

C:\..\BisonFlexCalculator/Includes/calc.hpp:17: multiple definition of 'symtab'
C:\..\BisonFlexCalculator/Includes/calc.hpp:17: first defined here
C:\..\BisonFlexCalculator/Includes/calc.hpp:17: multiple definition of 'symtab'
C:\..\BisonFlexCalculator/Includes/calc.hpp:17: first defined here
collect2.exe: error: ld returned 1 exit status

I got a header guard in the .hpp-file where symtab is declared, but yet it says that it got multiple definitions. I've uploaded the code to a github-repo. Can someone please help me understand what I'm doing wrong and how to solve my problem?

Thank you!

1 Answers1

0

The problem is that you have a definition of the variable symbol symtab[NHASH] in the header file. Each source file that includes this header, will define that symbol. Since all your source files include this header file, you will have multiple definitions of the same object and thus violate the ODR (One Definition Rule), hence the error message.

I see symtab is only used in the calcfunction.cpp, can you move it to that file? Otherwise, you can make sure to only declare it in the header by marking it extern (Look at this answer: How do I use extern to share variables between source files?).

Mikael H
  • 1,323
  • 7
  • 12
  • Thanks Mikael! Moving symtab[NHASH] solved it, I should have been able to understand this by my self.. But yet, the example in the book said that it should be in the .h-file. The example is in C, but that should not matter, right? – Isac Svensson Jun 15 '20 at 19:06
  • Not sure how C deals with ODR. Seems to be not as strict: https://stackoverflow.com/questions/34986335/does-c-have-one-definition-rule-like-c. – Mikael H Jun 15 '20 at 19:17
  • 1
    C has the "common extension allowing multiple definitions" (J.5.11 in the C11 spec) -- mulitple definitions of a symbol are allowed as long as all are compatible and at most one of them has an initializer. This is often just called the "common" extension, as it is using/supported by fortran-style COMMON symbols in the linker. – Chris Dodd Jun 15 '20 at 23:15
  • You might want to try the `%language "C++"` directive – Darryl Jun 16 '20 at 20:07