My version of Dev-C++ is 4.9.9.1 my OS is XP
I am trying to compile several .cpp files and one .h file and am getting multiple definition errors of the variables in the .h file. There are no redeclarations of them in the .cpp files.
Can anyone tell me whats causing this and how to get around this problem? The compile log follows. Below that is a copy of some of the source files.
init.o(.bss+0x0):init.cpp: multiple definition of tokenval'
main.o(.bss+0x0):main.cpp: first defined here
init.o(.bss+0x4):init.cpp: multiple definition oflineno'
main.o(.bss+0x4):main.cpp: first defined here
init.o(.bss+0x20):init.cpp: multiple definition of `symtable'
main.o(.bss+0x20):main.cpp: first defined here
.... there are lots more of these multiple def errors. Below is my Main.cpp, Init.cpp, global.h and lex.cpp
while(1)
{
t = getchar();
if (t == ' ' || t == '\t')
; /* strip out white space */
else if (t == '\n')
lineno = lineno + 1;
else if (isdigit(t)) /* t is a digit */
{
ungetc(t, stdin);
scanf("%d", &tokenval);
return NUM;
}
else if (isalpha(t)) /* t is a letter */
{
int p, b = 0;
while (isalnum(t)) /* t is alphanumeric */
{
lexbuf[b] = t;
t = getchar();
b = b + 1;
if (b >= BSIZE)
error("compiler error");
}
lexbuf[b] = EOS;
if (t != EOF)
ungetc(t, stdin);
p = lookup(lexbuf);
if (p == 0)
p = insert(lexbuf, ID);
tokenval = p;
return symtable[p].token;
}
else if (t == EOF)
return DONE;
else
{
tokenval = NONE;
return t;
}
}
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I took the declarations out of the global.h just to see if that was it, expected other prob's since these are used in several files but I get the same errors.
thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
When you changed Global.h you need to rebuild all, not just compile. I would guess that the problem is global.h. The errors are not caused by compiler include files.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Try declaring tokenval, symtable and the other globals extern in the header file and define them somewhere in a source file. I've had the same problem, and this solution worked.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2006-04-14
The problem is that you have instantiated (rather than declared) global data in the header. Each compilation unit that includes the header gets its own independent instance of the data, so that when the linker brings the units together, it finds multiple global data items with the same name.
global.h should contain:
extern int tokenval; / value of token attribute /
extern int lineno;
extern struct entry symtable[100]; / symbol table /
An additional file global.c is then needed that contains the data instantiation:
include "global.h"
int tokenval; / value of token attribute /
int lineno;
struct entry symtable[100]; / symbol table /
Now only one compilation unit instantiates the data, and all the other units reference thse single instances.
Another issue with your code that will cause problems in more complex applications is that you have not used 'include guards' in global.h.
/*global.h*******/
if !defined GLOBAL_H
define GLOBAL_H
// ... rest of global.h here ...
endif
/ End of file /
Use this pattern for all your header files, a unique macro is required for each one, it is normal to use something derived from the file name the file name (so long as it is unique). If you care to take a look at the standard headers, you will see something similar. Doing this ensures that you don run into problems when you use nested headers, and end up indirectly including the same twice.
Clifford
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you very much for the replies I will give it a try and do a "Rebuild All" when I get it coded up. I actually tried the extern keyword on the variables but I didn't try to the rebuild all button and I didn't know to use an object.c file. I'm pretty new at this.
thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2006-04-15
Note that the global data could also be instantiated in any of the existing sources, (as in yor commented out lines), and in some cases this is appropriate. Placing them in a separate file (or even multiple separate files) is only ome approach. However there must be only one instantiation of each global.
Note also that use of global data is usually indicitive of a failure of design. You should consider approaches for eradicating it. In the code you posted none on the global variables need to be global since they are only used within lexan().
Clifford
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
My version of Dev-C++ is 4.9.9.1 my OS is XP
I am trying to compile several .cpp files and one .h file and am getting multiple definition errors of the variables in the .h file. There are no redeclarations of them in the .cpp files.
Can anyone tell me whats causing this and how to get around this problem? The compile log follows. Below that is a copy of some of the source files.
Compiler: Default compiler
Building Makefile: "C:\CS380 Programs\BooksScanner_v2\Makefile.win"
Executing make...
make.exe -f "C:\CS380 Programs\BooksScanner_v2\Makefile.win" all
g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/include/c++/3.3.1" -I"C:/Dev-Cpp/include/c++/3.3.1/mingw32" -I"C:/Dev-Cpp/include/c++/3.3.1/backward" -I"C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include" -I"C:/Dev-Cpp/include"
g++.exe -c lexer.cpp -o lexer.o -I"C:/Dev-Cpp/include/c++/3.3.1" -I"C:/Dev-Cpp/include/c++/3.3.1/mingw32" -I"C:/Dev-Cpp/include/c++/3.3.1/backward" -I"C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include" -I"C:/Dev-Cpp/include"
g++.exe -c symbol.cpp -o symbol.o -I"C:/Dev-Cpp/include/c++/3.3.1" -I"C:/Dev-Cpp/include/c++/3.3.1/mingw32" -I"C:/Dev-Cpp/include/c++/3.3.1/backward" -I"C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include" -I"C:/Dev-Cpp/include"
g++.exe main.o init.o emitter.o error.o lexer.o parser.o symbol.o -o "BooksScanner_v2.exe" -L"C:/Dev-Cpp/lib"
init.o(.bss+0x0):init.cpp: multiple definition of
tokenval' main.o(.bss+0x0):main.cpp: first defined here init.o(.bss+0x4):init.cpp: multiple definition of
lineno'main.o(.bss+0x4):main.cpp: first defined here
init.o(.bss+0x20):init.cpp: multiple definition of `symtable'
main.o(.bss+0x20):main.cpp: first defined here
.... there are lots more of these multiple def errors. Below is my Main.cpp, Init.cpp, global.h and lex.cpp
/*main.c*******/
include "global.h"
include <string>
include <iostream>
include <iomanip>
include <fstream>
int main()
{
init();
parse();
exit(0);
/successful termination /
}
/*init.cpp*******/
include "global.h"
struct entry keywords[] =
{
"div", DIV,
"mod", MOD,
0, 0
};
void init() /loads keywords into symtable/
{
struct entry *p;
for (p = keywords; p->token; p++)
insert(p->lexptr, p->token);
}
/*global. h*******/
/#include <stdio.h> / load i/o routines */
include <cstring> / load character test routines/
include <fstream>
include <string>
include <iostream>
define BSIZE 128 / buffer size /
define NONE -1
define EOS '\0'
define NUM 256
define DIV 257
define MOD 258
define ID 259
define DONE 260
void init();
void parse();
int insert(char s[], int tok);
void emit(int t, int tval);
void error(char *m);
int lookup(char s[]);
int lexan();
void expr();
void term();
void factor();
void match(int t);
int tokenval; / value of token attribute /
int lineno;
struct entry / form of symbol table entry /
{
char *lexptr;
int token;
};
struct entry symtable[100]; / symbol table /
/* lexer.c ******/
include "global.h"
char lexbuf[BSIZE];
//int lineno = 1;
//int tokenval = NONE;
int lexan() / lexical analyzer /
{
int t;
}
I took the declarations out of the global.h just to see if that was it, expected other prob's since these are used in several files but I get the same errors.
thanks
When you changed Global.h you need to rebuild all, not just compile. I would guess that the problem is global.h. The errors are not caused by compiler include files.
Try declaring tokenval, symtable and the other globals extern in the header file and define them somewhere in a source file. I've had the same problem, and this solution worked.
The problem is that you have instantiated (rather than declared) global data in the header. Each compilation unit that includes the header gets its own independent instance of the data, so that when the linker brings the units together, it finds multiple global data items with the same name.
global.h should contain:
extern int tokenval; / value of token attribute /
extern int lineno;
extern struct entry symtable[100]; / symbol table /
An additional file global.c is then needed that contains the data instantiation:
include "global.h"
int tokenval; / value of token attribute /
int lineno;
struct entry symtable[100]; / symbol table /
Now only one compilation unit instantiates the data, and all the other units reference thse single instances.
Another issue with your code that will cause problems in more complex applications is that you have not used 'include guards' in global.h.
/*global.h*******/
if !defined GLOBAL_H
define GLOBAL_H
// ... rest of global.h here ...
endif
/ End of file /
Use this pattern for all your header files, a unique macro is required for each one, it is normal to use something derived from the file name the file name (so long as it is unique). If you care to take a look at the standard headers, you will see something similar. Doing this ensures that you don run into problems when you use nested headers, and end up indirectly including the same twice.
Clifford
slocombe and others,
Thank you very much for the replies I will give it a try and do a "Rebuild All" when I get it coded up. I actually tried the extern keyword on the variables but I didn't try to the rebuild all button and I didn't know to use an object.c file. I'm pretty new at this.
thanks
Note that the global data could also be instantiated in any of the existing sources, (as in yor commented out lines), and in some cases this is appropriate. Placing them in a separate file (or even multiple separate files) is only ome approach. However there must be only one instantiation of each global.
Note also that use of global data is usually indicitive of a failure of design. You should consider approaches for eradicating it. In the code you posted none on the global variables need to be global since they are only used within lexan().
Clifford