'Multiple definition of' g++ compiler error

Hi all,

I have 2 .cpp files and 1 header (.h) file.

I have an array which is used in both .cpp files. Hence, I have declared and initialised it in the header file.

1
2
3
4
5
6
// Main.h
struct Abcd
{
   //do something here
};
Abcd users[50];


However, g++ reported the following error:
1
2
3
/tmp/ccblPtfK.o:(.bss+0x0): multiple definition of `users'
/tmp/ccR62VWy.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status 


After some research, I found out that header files are meant for variable declaration only. I changed it to:
Abcd users[];

But here is when I am stumped. If I leave the array size empty, that means that I will have to define it in both .cpp files, which will result in the 'multiple definition' error too.

Any help is greatly appreciated.
Last edited on
Hi,

You need to have header guards and / or #pragma once these will stop the file being included more than once.

1
2
3
4
5
6
7
8
9
10
11
#pragma once  // not standard, but has wide support, does a better job than humans
#ifndef MAIN_H
#define MAIN_H

struct Abcd
{
   //do something here
};
Abcd users[50];

#endif 



Edit:

My IDE does this for me automatically :+)
Last edited on
Hi TheIdeasMan,

I am still facing the same issue even after adding #pragma once and #ifndef MAIN_H and #define MAIN_H and #endif.

I tried adding either 1 of them, but the same error persists.

Edit:
Hmm putting a static keyword did the trick, but I am not too sure about the side effects..
static Abcd users[50];

Edit:
The array is useless for my use case when it is static. The array is always empty even when values are written to it.
Last edited on
Hi, DoodleDoo.
The problem you put can be solved by accessing scope of other files, what's so called 'global scope', in this way:
myheader.h:
1
2
3
4
5
6
7
#ifndef MYHEADER_H
#define MYHEADER_H

struct Abcd
{};

#endif // MYHEADER_H 


mycpp:
1
2
3
4
5
6
7
8
9
#include <iostream>
#include "myheader.h"

extern Abcd users[];

void printArrayAddress()
{
    std::cout << "Memory address of users[]: " << users << '\n';
}


main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include "myheader.h"

Abcd users[50];

void printArrayAddress();

int main()
{
    std::cout << "Memory address of users[]: " << users << '\n';
    printArrayAddress();

    return 0;
}


But that's really a bad idea, since it can leads to subtle errors very difficult to discover.
It should be far, far better if you:
1) avoided C-style array and used std::vector (or std::array, if you are sure about dimension)
2) passed the array/vector/whatever as a parameter between functions instead of declaring it globally.

Include guards / header guards, call them as you prefer, won't be of any help in this situation, since every translation unit is compiled before being linked, i.e. include guards protect you from including twice the same file from the same translation unit, not when you are linking to other files.
Last edited on
Hi Enoizat,

Thanks for the advice. I managed to remove the need to declare arrays in the header file by only using the array in a single source file.

I'll take a look at vectors, looks promising :)

I'll need some time to digest the translation unit theory, will get back to it soon :)
Topic archived. No new replies allowed.