Multiple definition [...] first define here

23,071

Solution 1

You must keep only the declarations in a .h file, not the definitions, lest you should get any linker errors. These

int I_Macroblock_Modes[27][7];
int P_and_SP_macroblock_modes[32][7];
int B_Macroblock_Modes[50][7];

are definitions, not intuitive as it may seem. Change these to

extern int I_Macroblock_Modes[27][7];
extern int P_and_SP_macroblock_modes[32][7];
extern int B_Macroblock_Modes[50][7];

and you should be fine

Solution 2

It's not "just defines". You are declaring variables inside it, therefore every time that gets included your are redeclaring global variables.

If what you want is to access I_Macroblock_Modes from other .c/.cpp files, in the macroblocktables.h header you should put:

//resides in macroblocktables.cpp
extern int I_Macroblock_Modes[27][7];
extern int P_and_SP_macroblock_modes[32][7];
extern int B_Macroblock_Modes[50][7];

// the rest of it

Because those int arrays are defined in macroblocktables.cpp, right?

In C/C++ everytime you do something like:

int myarray[4];
char mychar;

or more generally

type var_name;

you are telling to the compiler: please allocate on the stack for me, a variable named X that has type T.

when you #include header.h, in the most basic explanation, you are telling the preprocessor: open header.h ctrl+c all of it, and ctrl+v it here. Then that preprocessed source file is fed to your compiler and every time it sees type var_name it will do what i explained above.

Sorry if this is too much info, but I just felt like writing it :P

Share:
23,071
Pedro Dusso
Author by

Pedro Dusso

I am interested in database systems, artificial intelligence, and big data processing to support data-intensive science. I have worked as research assistant with distributed monitoring systems, federated cloud services, and traceability of engineering requirements. As intern, I have worked with Intranet web portals, documentation, and mobile.

Updated on June 23, 2020

Comments

  • Pedro Dusso
    Pedro Dusso almost 4 years

    I'm writing a H264 parser (no OO), but I'm trying to use some modules to organize better the things.

    I'm having this problems:

    `CMakeFiles/server.dir/mainclass.cpp.o:(.bss+0x0): multiple definition of `I_Macroblock_Modes'  
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x0): first defined here  
    `CMakeFiles/server.dir/mainclass.cpp.o:(.bss+0x300): multiple definition of `P_and_SP_macroblock_modes'  
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x300): first defined here  
    `CMakeFiles/server.dir/mainclass.cpp.o:(.bss+0x680): multiple definition of `B_Macroblock_Modes' 
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x680): first defined here  
    `CMakeFiles/server.dir/thRunAppl.cpp.o:(.bss+0x0): multiple definition of `I_Macroblock_Modes'  
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x0): first defined here  
    `CMakeFiles/server.dir/thRunAppl.cpp.o:(.bss+0x300): multiple definition of `P_and_SP_macroblock_modes'  
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x300): first defined here  
    `CMakeFiles/server.dir/thRunAppl.cpp.o:(.bss+0x680): multiple definition of `B_Macroblock_Modes'  
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x680): first defined here  
    `CMakeFiles/server.dir/h.264parser.cpp.o:(.bss+0x0): multiple definition of `I_Macroblock_Modes'  
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x0): first defined here  
    `CMakeFiles/server.dir/h.264parser.cpp.o:(.bss+0x300): multiple definition of `P_and_SP_macroblock_modes'  
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x300): first defined here  
    `CMakeFiles/server.dir/h.264parser.cpp.o:(.bss+0x680): multiple definition of `B_Macroblock_Modes'  
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x680): first defined here  
    `CMakeFiles/server.dir/moc_mainclass.cxx.o:(.bss+0x0): multiple definition of `I_Macroblock_Modes'
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x0): first defined here
    `CMakeFiles/server.dir/moc_mainclass.cxx.o:(.bss+0x300): multiple definition of `P_and_SP_macroblock_modes'
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x300): first defined here
    `CMakeFiles/server.dir/moc_mainclass.cxx.o:(.bss+0x680): multiple definition of `B_Macroblock_Modes'
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x680): first defined here
    `CMakeFiles/server.dir/moc_thRunAppl.cxx.o:(.bss+0x0): multiple definition of `I_Macroblock_Modes'
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x0): first defined here
    `CMakeFiles/server.dir/moc_thRunAppl.cxx.o:(.bss+0x300): multiple definition of `P_and_SP_macroblock_modes'
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x300): first defined here
    `CMakeFiles/server.dir/moc_thRunAppl.cxx.o:(.bss+0x680): multiple definition of `B_Macroblock_Modes'
    `CMakeFiles/server.dir/main.cpp.o:(.bss+0x680): first defined here
    `CMakeFiles/server.dir/h.264parser.cpp.o: In function `MbPartPredMode(int, int)':  
    `h.264parser.cpp:(.text+0xf0): undefined reference to `B_macroblockmodes(int, int)'  
    `h.264parser.cpp:(.text+0x104): undefined reference to `B_macroblockmodes(int, int)'  
    `h.264parser.cpp:(.text+0x111): undefined reference to `I_macroblockmodes(int, int)'  
    `h.264parser.cpp:(.text+0x124): undefined reference to `P_and_SP_macroblockmodes(int, int)'  
    `h.264parser.cpp:(.text+0x134): undefined reference to `P_and_SP_macroblockmodes(int, int)' 
    

    My scenario is:

    macroblocktypes.h. just with defines

    macroblocktables.h:

    #include "macroblocktypes.h"
    
    int I_Macroblock_Modes[27][7];
    int P_and_SP_macroblock_modes[32][7];
    int B_Macroblock_Modes[50][7];
    
    int I_macroblockmodes(int line, int column);
    int P_and_SP_macroblockmodes(int line, int column);
    int B_macroblockmodes(int line, int column);
    

    macroblocktables.cpp, with a array and a function defined like this for each array and function on .h file.

    #include "macroblocktables.h"
    int I_macroblock_modes[27][7] ={
    {0, I_4x4, 0, Intra_4x4, NA, NA, NA},
    //If this line was to be commented out, the MbPartPredMode macro would have to be changed
    //since it relies on the linear rise of the value in the first column.
    //{0,   I_NxN,          1,  Intra_8x8,   NA, NA, NA},
    {1, I_16x16_0_0_0, NA, Intra_16x16, 0, 0, 0},
    {2, I_16x16_1_0_0, NA, Intra_16x16, 1, 0, 0},
    {3, I_16x16_2_0_0, NA, Intra_16x16, 2, 0, 0},
    {4, I_16x16_3_0_0, NA, Intra_16x16, 3, 0, 0},
    {5, I_16x16_0_1_0, NA, Intra_16x16, 0, 1, 0},
    {6, I_16x16_1_1_0, NA, Intra_16x16, 1, 1, 0},
    {7, I_16x16_2_1_0, NA, Intra_16x16, 2, 1, 0},
    {8, I_16x16_3_1_0, NA, Intra_16x16, 3, 1, 0},
    {9, I_16x16_0_2_0, NA, Intra_16x16, 0, 2, 0},
    {10, I_16x16_1_2_0, NA, Intra_16x16, 1, 2, 0},
    {11, I_16x16_2_2_0, NA, Intra_16x16, 2, 2, 0},
    {12, I_16x16_3_2_0, NA, Intra_16x16, 3, 2, 0},
    {13, I_16x16_0_0_1, NA, Intra_16x16, 0, 0, 15},
    {14, I_16x16_1_0_1, NA, Intra_16x16, 1, 0, 15},
    {15, I_16x16_2_0_1, NA, Intra_16x16, 2, 0, 15},
    {16, I_16x16_3_0_1, NA, Intra_16x16, 3, 0, 15},
    {17, I_16x16_0_1_1, NA, Intra_16x16, 0, 1, 15},
    {18, I_16x16_1_1_1, NA, Intra_16x16, 1, 1, 15},
    {19, I_16x16_2_1_1, NA, Intra_16x16, 2, 1, 15},
    {20, I_16x16_3_1_1, NA, Intra_16x16, 3, 1, 15},
    {21, I_16x16_0_2_1, NA, Intra_16x16, 0, 2, 15},
    {22, I_16x16_1_2_1, NA, Intra_16x16, 1, 2, 15},
    {23, I_16x16_2_2_1, NA, Intra_16x16, 2, 2, 15},
    {24, I_16x16_3_2_1, NA, Intra_16x16, 3, 2, 15},
    {25, I_PCM, NA, NA, NA, NA, NA}};
    
    int P_and_SP_macroblock_modes[32][7] = {
    {0, P_L0_16x16, 1, Pred_L0, NA, 16, 16},
    {1, P_L0_L0_16x8, 2, Pred_L0, Pred_L0, 16, 8},
    {2, P_L0_L0_8x16, 2, Pred_L0, Pred_L0, 8, 16},
    {3, P_8x8, 4, NA, NA, 8, 8},
    {4, P_8x8ref0, 4, NA, NA, 8, 8},
    {0, I_4x4, 0, Intra_4x4, NA, NA, NA},
    {1, I_16x16_0_0_0, NA, Intra_16x16, 0, 0, 0},
    {2, I_16x16_1_0_0, NA, Intra_16x16, 1, 0, 0},
    {3, I_16x16_2_0_0, NA, Intra_16x16, 2, 0, 0},
    {4, I_16x16_3_0_0, NA, Intra_16x16, 3, 0, 0},
    {5, I_16x16_0_1_0, NA, Intra_16x16, 0, 1, 0},
    {6, I_16x16_1_1_0, NA, Intra_16x16, 1, 1, 0},
    {7, I_16x16_2_1_0, NA, Intra_16x16, 2, 1, 0},
    {8, I_16x16_3_1_0, NA, Intra_16x16, 3, 1, 0},
    {9, I_16x16_0_2_0, NA, Intra_16x16, 0, 2, 0},
    {10, I_16x16_1_2_0, NA, Intra_16x16, 1, 2, 0},
    {11, I_16x16_2_2_0, NA, Intra_16x16, 2, 2, 0},
    {12, I_16x16_3_2_0, NA, Intra_16x16, 3, 2, 0},
    {13, I_16x16_0_0_1, NA, Intra_16x16, 0, 0, 15},
    {14, I_16x16_1_0_1, NA, Intra_16x16, 1, 0, 15},
    {15, I_16x16_2_0_1, NA, Intra_16x16, 2, 0, 15},
    {16, I_16x16_3_0_1, NA, Intra_16x16, 3, 0, 15},
    {17, I_16x16_0_1_1, NA, Intra_16x16, 0, 1, 15},
    {18, I_16x16_1_1_1, NA, Intra_16x16, 1, 1, 15},
    {19, I_16x16_2_1_1, NA, Intra_16x16, 2, 1, 15},
    {20, I_16x16_3_1_1, NA, Intra_16x16, 3, 1, 15},
    {21, I_16x16_0_2_1, NA, Intra_16x16, 0, 2, 15},
    {22, I_16x16_1_2_1, NA, Intra_16x16, 1, 2, 15},
    {23, I_16x16_2_2_1, NA, Intra_16x16, 2, 2, 15},
    {24, I_16x16_3_2_1, NA, Intra_16x16, 3, 2, 15},
    {25, I_PCM, NA, NA, NA, NA, NA},
    {NA, P_Skip, 1, Pred_L0, NA, 16, 16}};
    
    int B_macroblock_modes[50][7] = {
    {0, B_Direct_16x16, NA, Direct, NA, 8, 8},
    {1, B_L0_16x16, 1, Pred_L0, NA, 16, 16},
    {2, B_L1_16x16, 1, Pred_L1, NA, 16, 16},
    {3, B_Bi_16x16, 1, BiPred, NA, 16, 16},
    {4, B_L0_L0_16x8, 2, Pred_L0, Pred_L0, 16, 8},
    {5, B_L0_L0_8x16, 2, Pred_L0, Pred_L0, 8, 16},
    {6, B_L1_L1_16x8, 2, Pred_L1, Pred_L1, 16, 8},
    {7, B_L1_L1_8x16, 2, Pred_L1, Pred_L1, 8, 16},
    {8, B_L0_L1_16x8, 2, Pred_L0, Pred_L1, 16, 8},
    {9, B_L0_L1_8x16, 2, Pred_L0, Pred_L1, 8, 16},
    {10, B_L1_L0_16x8, 2, Pred_L1, Pred_L0, 16, 8},
    {11, B_L1_L0_8x16, 2, Pred_L1, Pred_L0, 8, 16},
    {12, B_L0_Bi_16x8, 2, Pred_L0, BiPred, 16, 8},
    {13, B_L0_Bi_8x16, 2, Pred_L0, BiPred, 8, 16},
    {14, B_L1_Bi_16x8, 2, Pred_L1, BiPred, 16, 8},
    {15, B_L1_Bi_8x16, 2, Pred_L1, BiPred, 8, 16},
    {16, B_Bi_L0_16x8, 2, BiPred, Pred_L0, 16, 8},
    {17, B_Bi_L0_8x16, 2, BiPred, Pred_L0, 8, 16},
    {18, B_Bi_L1_16x8, 2, BiPred, Pred_L1, 16, 8},
    {19, B_Bi_L1_8x16, 2, BiPred, Pred_L1, 8, 16},
    {20, B_Bi_Bi_16x8, 2, BiPred, BiPred, 16, 8},
    {21, B_Bi_Bi_8x16, 2, BiPred, BiPred, 8, 16},
    {22, B_8x8, 4, NA, NA, 8, 8},
    {0, I_4x4, 0, Intra_4x4, NA, NA, NA},
    {1, I_16x16_0_0_0, NA, Intra_16x16, 0, 0, 0},
    {2, I_16x16_1_0_0, NA, Intra_16x16, 1, 0, 0},
    {3, I_16x16_2_0_0, NA, Intra_16x16, 2, 0, 0},
    {4, I_16x16_3_0_0, NA, Intra_16x16, 3, 0, 0},
    {5, I_16x16_0_1_0, NA, Intra_16x16, 0, 1, 0},
    {6, I_16x16_1_1_0, NA, Intra_16x16, 1, 1, 0},
    {7, I_16x16_2_1_0, NA, Intra_16x16, 2, 1, 0},
    {8, I_16x16_3_1_0, NA, Intra_16x16, 3, 1, 0},
    {9, I_16x16_0_2_0, NA, Intra_16x16, 0, 2, 0},
    {10, I_16x16_1_2_0, NA, Intra_16x16, 1, 2, 0},
    {11, I_16x16_2_2_0, NA, Intra_16x16, 2, 2, 0},
    {12, I_16x16_3_2_0, NA, Intra_16x16, 3, 2, 0},
    {13, I_16x16_0_0_1, NA, Intra_16x16, 0, 0, 15},
    {14, I_16x16_1_0_1, NA, Intra_16x16, 1, 0, 15},
    {15, I_16x16_2_0_1, NA, Intra_16x16, 2, 0, 15},
    {16, I_16x16_3_0_1, NA, Intra_16x16, 3, 0, 15},
    {17, I_16x16_0_1_1, NA, Intra_16x16, 0, 1, 15},
    {18, I_16x16_1_1_1, NA, Intra_16x16, 1, 1, 15},
    {19, I_16x16_2_1_1, NA, Intra_16x16, 2, 1, 15},
    {20, I_16x16_3_1_1, NA, Intra_16x16, 3, 1, 15},
    {21, I_16x16_0_2_1, NA, Intra_16x16, 0, 2, 15},
    {22, I_16x16_1_2_1, NA, Intra_16x16, 1, 2, 15},
    {23, I_16x16_2_2_1, NA, Intra_16x16, 2, 2, 15},
    {24, I_16x16_3_2_1, NA, Intra_16x16, 3, 2, 15},
    {25, I_PCM, NA, NA, NA, NA, NA},
    {NA, B_Skip, NA, Direct, NA, 8, 8}};
    
    int I_macroblockmodes(int line, int column) {
    if (line < 27 && column < 7)
        return I_macroblock_modes[line][column];
    else {
        if (line >= 27) {
            return -10000; //line is bigger than the array size
        } else {
            return -20000; //column is bigger than the array size
        }
    }}
    //Inter prediction slices - Macroblock types
    //Defined strictly by norm, page 121.
    
    //(Table 7-13 Macroblock type values 0 to 4 for P and SP slices)
    /*
    First column:   mb_type
    Second column:  Name of mb_type
    Third column:   NumMbPart( mb_type )
    Fourth column:  MbPartPredMode( mb_type, 0 )
    Fifth column:   MbPartPredMode( mb_type, 1 )
    Sixth column:   MbPartWidth( mb_type )
    Seventh column: MbPartHeight( mb_type )
    */
    int P_and_SP_macroblockmodes(int line, int column){
     if (line < 32 && column < 7)
        return P_and_SP_macroblock_modes[line][column];
    else {
        if (line >= 32) {
            return -10000; //line is bigger than the array size
        } else {
            return -20000; //column is bigger than the array size
        }
    }}
    
    
    
    //p94. Table 7-14 – Macroblock type values 0 to 22 for B slices
    /*
    First column:   mb_type
    Second column:  Name of mb_type
    Third column:   NumMbPart( mb_type )
    Fourth column:  MbPartPredMode( mb_type, 0 )
    Fifth column:   MbPartPredMode( mb_type, 1 )
    Sixth column:   MbPartWidth( mb_type )
    Seventh column: MbPartHeight( mb_type )
     */
    int B_macroblockmodes(int line, int column){
     if (line < 50 && column < 7)
        return B_macroblock_modes[line][column];
    else {
        if (line >= 50) {
            return -10000; //line is bigger than the array size
        } else {
            return -20000; //column is bigger than the array size
        }
    }}
    

    And finally my h.264 files (.cpp and .h). Im including in the .h the macroblocktable.h and macroblocktype.h, and in the h.264.cpp just the h.264.h.

    I would like to use the functions from the macroblocktable.cpp in the h.264.cpp.

    Thanks in advance

  • Pedro Dusso
    Pedro Dusso almost 13 years
    Sorry dont make it clear, but the file with just defines is the macroblocktypes.h. I know the macroblocktable.h have variables declared on it
  • Pedro Dusso
    Pedro Dusso almost 13 years
    Thanks for your answer but I dont wanna access the arrays outside, but kind of encapsulate then in the macroblocktable.cpp and call the functions from that .cpp. I remove the declarations from the .h, and the 'multiple definition' errors stop; but i still having the 'h.264parser.cpp:(.text+0x104): undefined reference to `B_macroblockmodes(int, int)'' error when I try to call the functions from the h.265.cpp. =(
  • Armen Tsirunyan
    Armen Tsirunyan almost 13 years
    @Pmdusso: You don't need to remove any declarations from anywhere. Follow these steps: 1) In the .h file add the extern keyword to the array declarations. Leave the array definitions in the cpp file intact. 2) Add the definition of B_macroblockmodes(int, int) function to the cpp file (you have forgotten to write the body, hence the error)
  • Pedro Dusso
    Pedro Dusso almost 13 years
    if you mean write the B_macroblockmodes(int, int) in the macroblocktable.cpp, I did! You can see in the question... and I write the definitions of the arrays back in the macroblocktable.h with the extern, thanks!
  • Armen Tsirunyan
    Armen Tsirunyan almost 13 years
    @Pmdusso: er... no, you haven't. Where is the body of that function?
  • Pedro Dusso
    Pedro Dusso almost 13 years
    ah... sorry... I just wrote the int I_macroblockmodes(int line, int column) to save space here... but all three are there, I will edit it. Thats it, they are there now.
  • Pedro Dusso
    Pedro Dusso almost 13 years
    @hexa should i make the functions extern also? Making the arrays extern resolved the multiple definition... but i dont know what to do with the functions now!
  • Vinicius Kamakura
    Vinicius Kamakura almost 13 years
    the function prototypes are fine :) en.wikipedia.org/wiki/Function_prototype
  • Pedro Dusso
    Pedro Dusso almost 13 years
    yep they are but still having 'undefined reference to' error from the h.264.cpp... =/
  • Vinicius Kamakura
    Vinicius Kamakura almost 13 years
    are you including the .h on h264.cpp? with the added extern for the arrays?