Connecting Tech Pros Worldwide Forums | Help | Site Map

Help with Global structs in headers and multiple definitions

Panda2
Guest
 
Posts: n/a
#1: Jul 23 '05
I'm getting multple definition errors for the struct in the following,
and I don't know how to get around it. I've tried using extern (which
I don't really understand) but it didn't help (maybe used it wrong).

I'm compiling with Dev-Cpp and the code works when the "stuff.cpp" is
included directly in main. I'd appreciate it if someone can explain
how I can use a gloablly defined struct over several files..

ps: I know theres some goofy, crappy, and awful use of c++.. Forgive
me, I'm very bad at this...

File 1: main.cpp
/////////////////////////////
#include "globals.h"
using namespace std;

int main(int argc, char *argv[])
{
float EMA[100];
for(int a=0; a<20; a++){numbers[a].data=a;}

CalcEMA (numbers, EMA, 0.2, 1, 20);

for(int x=0; x<20; x++){cout << EMA[x] << "\n";}

system("PAUSE");
return EXIT_SUCCESS;
}

File 2: stuff.cpp
/////////////////////////////////
#include "globals.h"

VOID CalcEMA (Test_m input[], float EMA[], float fPerc, int nType, int
nTData)
{
/* Calculates exponential moving averages */
if(nType == 1){EMA[0]= input[0].data;}
for(int n=1; n<nTData; n++)
{
if(nType == 1){EMA[n]=( ( (input[n].data - EMA[n-1]) * fPerc) +
EMA[n-1] );}
}
return;
}

File 3: globals.h
////////////////////////////////////
#ifndef _GLOBALS_H_
#define _GLOBALS_H_

#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <fstream>
#include <string>
#include <time.h>

struct Test_m {
float data;
}numbers[100];

VOID CalcEMA (Test_m input[], float EMA[], float fPerc, int nType, int
nTData);

#endif


/////////////////////////////////
Compiler output:

Compiler: Default compiler
Building Makefile: "C:\Dev-Cpp\TestFiles\Makefile.win"
Executing make...
make.exe -f "C:\Dev-Cpp\TestFiles\Makefile.win" all
g++.exe main.o stuff.o -o "Project1.exe" -L"C:/Dev-Cpp/lib"

stuff.o(.bss+0x0):stuff.cpp: multiple definition of `numbers'
main.o(.bss+0x0):main.cpp: first defined here

make.exe: *** [Project1.exe] Error 1

Execution terminated


GB
Guest
 
Posts: n/a
#2: Jul 23 '05

re: Help with Global structs in headers and multiple definitions


Panda2 wrote:[color=blue]
> I'm getting multple definition errors for the struct in the following,
> and I don't know how to get around it. I've tried using extern (which
> I don't really understand) but it didn't help (maybe used it wrong).
>
> I'm compiling with Dev-Cpp and the code works when the "stuff.cpp" is
> included directly in main. I'd appreciate it if someone can explain
> how I can use a gloablly defined struct over several files..
>
> ps: I know theres some goofy, crappy, and awful use of c++.. Forgive
> me, I'm very bad at this...
>
> File 1: main.cpp
> /////////////////////////////
> #include "globals.h"
> using namespace std;
>
> int main(int argc, char *argv[])
> {
> float EMA[100];
> for(int a=0; a<20; a++){numbers[a].data=a;}
>
> CalcEMA (numbers, EMA, 0.2, 1, 20);
>
> for(int x=0; x<20; x++){cout << EMA[x] << "\n";}
>
> system("PAUSE");
> return EXIT_SUCCESS;
> }
>
> File 2: stuff.cpp
> /////////////////////////////////
> #include "globals.h"
>
> VOID CalcEMA (Test_m input[], float EMA[], float fPerc, int nType, int
> nTData)
> {
> /* Calculates exponential moving averages */
> if(nType == 1){EMA[0]= input[0].data;}
> for(int n=1; n<nTData; n++)
> {
> if(nType == 1){EMA[n]=( ( (input[n].data - EMA[n-1]) * fPerc) +
> EMA[n-1] );}
> }
> return;
> }
>
> File 3: globals.h
> ////////////////////////////////////
> #ifndef _GLOBALS_H_
> #define _GLOBALS_H_
>
> #include <cstdlib>
> #include <iostream>
> #include <windows.h>
> #include <fstream>
> #include <string>
> #include <time.h>
>
> struct Test_m {
> float data;
> }numbers[100];
>
> VOID CalcEMA (Test_m input[], float EMA[], float fPerc, int nType, int
> nTData);
>
> #endif
>
>
> /////////////////////////////////
> Compiler output:
>
> Compiler: Default compiler
> Building Makefile: "C:\Dev-Cpp\TestFiles\Makefile.win"
> Executing make...
> make.exe -f "C:\Dev-Cpp\TestFiles\Makefile.win" all
> g++.exe main.o stuff.o -o "Project1.exe" -L"C:/Dev-Cpp/lib"
>
> stuff.o(.bss+0x0):stuff.cpp: multiple definition of `numbers'
> main.o(.bss+0x0):main.cpp: first defined here
>
> make.exe: *** [Project1.exe] Error 1
>
> Execution terminated
>[/color]

Note that you are getting a linker error, not a compiler error. It is
happening because you are giving each of your two translation units
(main.cpp and stuff.cpp) a copy of the "numbers" object, and it has
external linkage in each. You need to define only the type in the header
file, and define the variable on one of the cpp files.

Gregg
E. Robert Tisdale
Guest
 
Posts: n/a
#3: Jul 23 '05

re: Help with Global structs in headers and multiple definitions


Panda2 wrote:
[color=blue]
> I'm getting multple definition errors for the struct in the following,
> and I don't know how to get around it. I've tried using extern (which
> I don't really understand) but it didn't help (maybe I used it wrong).
>
> I'm compiling with Dev-Cpp and the code works when the "stuff.cpp" is
> included directly in main. I'd appreciate it if someone can explain
> how I can use a gloablly defined struct over several files..[/color]

You need to put the *definition* of numbers to stuff.cpp and
put an extern *declaration* in globals.h
You can *declare* and object as many times as you wish but
you can *define* it only once.
[color=blue]
> cat globals.h[/color]
#ifndef GUARD_GLOBALS_H
#define GUARD_GLOBALS_H 1

#include <cstdlib>
#include <iostream>
// #include <windows.h>
#include <fstream>
#include <string>
#include <time.h>

struct Test_m {
float data;
};

const
size_t size = 100;
extern
Test_m numbers[100]; // declaration

float* CalcEMA(float EMA[], const Test_m input[],
float fPerc, int nType, size_t nTData);

#endif//GUARD_GLOBALS_H
[color=blue]
> cat stuff.cpp[/color]
#include "globals.h"

Test_m numbers[size]; // definition

float* CalcEMA(float EMA[], const Test_m input[],
const float fPerc, const int nType, const size_t nTData) {
// Calculates exponential moving averages
if (nType == 1) {
EMA[0] = input[0].data;
}
for (size_t n = 1; n < nTData; ++n) {
if (nType == 1) {
EMA[n] = (((input[n].data - EMA[n-1])*fPerc) + EMA[n-1]);
}
}
return EMA;
}
[color=blue]
> cat main.cpp[/color]
#include "globals.h"

int main(int argc, char *argv[]) {
const
size_t n = 20;
float EMA[size];
for (size_t a = 0; a < n; ++a) {
numbers[a].data = a;
}

CalcEMA(EMA, numbers, 0.2, 1, n);

for(size_t x = 0; x < n; ++x) {
std::cout << EMA[x] << std::endl;
}

system("PAUSE");
return EXIT_SUCCESS;
}
[color=blue]
> g++ -Wall -ansi -pedantic -o main main.cpp stuff.cpp
> ./main[/color]
0
0.2
0.56
1.048
1.6384
2.31072
3.04858
3.83886
4.67109
5.53687
6.4295
7.3436
8.27488
9.2199
10.1759
11.1407
12.1126
13.0901
14.0721
15.0576
sh: line 1: PAUSE: command not found
Closed Thread