Ошибка multiple definition of first defined here

The problem here is that you are including commands.c in commands.h before the function prototype. Therefore, the C pre-processor inserts the content of commands.c into commands.h before the function prototype. commands.c contains the function definition. As a result, the function definition ends up before than the function declaration causing the error.

The content of commands.h after the pre-processor phase looks like this:

#ifndef COMMANDS_H_
#define COMMANDS_H_

// function definition
void f123(){

}

// function declaration
void f123();

#endif /* COMMANDS_H_ */

This is an error because you can’t declare a function after its definition in C. If you swapped #include "commands.c" and the function declaration the error shouldn’t happen because, now, the function prototype comes before the function declaration.

However, including a .c file is a bad practice and should be avoided. A better solution for this problem would be to include commands.h in commands.c and link the compiled version of command to the main file. For example:

commands.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123(); // function declaration

#endif

commands.c

#include "commands.h"

void f123(){} // function definition

elch10

40 / 21 / 3

Регистрация: 27.04.2015

Сообщений: 176

1

29.08.2017, 10:45. Показов 37096. Ответов 9

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Есть header:

C++
1
2
3
4
5
6
7
8
9
10
11
12
//base.hpp
#ifndef BASE_HPP
#define BASE_HPP
 
struct Coord {
    int x, y;
};
 
bool isValidCoord(const Coord& c) 
{
    return true;
}

Он включается во многие другие хидеры. Но проблема в том, что у меня есть циклические ссылки, т.е. один файл включает другой, а другой включает первый. Выглядит все примерно так:

C++
1
2
3
4
5
6
7
8
//Player.hpp
#ifndef PLAYER_HPP
#define PLAYER_HPP
 
#include "base.hpp"
 
//что то
#endif
C++
1
2
3
4
5
6
7
8
//Figure.hpp
#ifndef FIGURE_HPP
#define FIGURE_HPP
 
#include "Player.hpp"
 
//что-то
#endif
C++
1
2
3
4
5
6
7
8
9
//State.hpp
#ifndef STATE_HPP
#define STATE_HPP
 
#include "Resources.hpp"
#include "Game.hpp"
 
//что то
#endif
C++
1
2
3
4
5
6
7
8
//Game.hpp
#ifndef GAME_HPP
#define GAME_HPP
 
#include "State.hpp"
 
//что то
#endif
C++
1
2
3
4
5
6
7
8
9
10
//Resources.hpp
#ifndef RESOURCES_HPP
#define RESOURCES_HPP
 
#include "base.hpp"
#include "Figure.hpp"
#include "Player.hpp"
 
//что то
#endif

После компиляции линкер выдает:

Код

build/Debug/GNU-Linux/Game.o: In function `isValidCoord(Coord const&)':
/home/elchin/CppApplication_1/base.hpp:42: multiple definition of `isValidCoord(Coord const&)'
build/Debug/GNU-Linux/Figure.o:/home/elchin/CppApplication_1/base.hpp:42: first defined here
build/Debug/GNU-Linux/Player.o: In function `isValidCoord(Coord const&)':
/home/elchin/CppApplication_1/base.hpp:42: multiple definition of `isValidCoord(Coord const&)'
build/Debug/GNU-Linux/Figure.o:/home/elchin/CppApplication_1/base.hpp:42: first defined here
build/Debug/GNU-Linux/Resources.o: In function `isValidCoord(Coord const&)':
/home/elchin/CppApplication_1/base.hpp:42: multiple definition of `isValidCoord(Coord const&)'
build/Debug/GNU-Linux/Figure.o:/home/elchin/CppApplication_1/base.hpp:42: first defined here
build/Debug/GNU-Linux/State.o: In function `isValidCoord(Coord const&)':
/home/elchin/CppApplication_1/base.hpp:42: multiple definition of `isValidCoord(Coord const&)'
build/Debug/GNU-Linux/Figure.o:/home/elchin/CppApplication_1/base.hpp:42: first defined here

Т.е.я понимаю, что происходит несколько определений, но я не пойму почему инклуд гуарды не спасают. Как можно разрешить эту проблему?



0



GbaLog-

Любитель чаепитий

3737 / 1796 / 563

Регистрация: 24.08.2014

Сообщений: 6,015

Записей в блоге: 1

29.08.2017, 11:43

2

Цитата
Сообщение от elch10
Посмотреть сообщение

C++
1
2
//State.hpp
#include "Game.hpp"

Цитата
Сообщение от elch10
Посмотреть сообщение

C++
1
2
//Game.hpp
#include "State.hpp"

знаете, как директива препроцессора include работает?



1



Байт

Диссидент

Эксперт C

27499 / 17187 / 3784

Регистрация: 24.12.2010

Сообщений: 38,716

29.08.2017, 12:01

3

Один из способов

C++
1
inline bool isValidCoord(const Coord& c)

Другой — вынести реализацию из хедера в CPP
И. да, повторю за предыдущим оратором

Цитата
Сообщение от GbaLog-
Посмотреть сообщение

знаете, как директива препроцессора include работает?

Цитата
Сообщение от elch10
Посмотреть сообщение

не пойму почему инклуд гуарды не спасают

В каждом из cpp- модулей (и объектных o- модулях) будет реализация этой функции. Линковщик в замешательстве — какую из них использовать?



2



Модератор

Эксперт по электронике

8809 / 6592 / 894

Регистрация: 14.02.2011

Сообщений: 23,182

29.08.2017, 12:08

4

Лучший ответ Сообщение было отмечено elch10 как решение

Решение

если возникнет вопрос с переменными
то для них есть extern

Добавлено через 4 минуты

Цитата
Сообщение от elch10
Посмотреть сообщение

но я не пойму почему инклуд гуарды не спасают.

потому что Си файлы компилируются в разное время и при компиляции одного компилятор ничего не знает про другой
создаются куча объектных файлов не связанных друг с другом
а вот линковшик видит все объектные файлы и

Цитата
Сообщение от Байт
Посмотреть сообщение

Линковщик в замешательстве



2



Диссидент

Эксперт C

27499 / 17187 / 3784

Регистрация: 24.12.2010

Сообщений: 38,716

29.08.2017, 12:08

5

Цитата
Сообщение от ValeryS
Посмотреть сообщение

если возникнет вопрос с переменными
то для них есть extern

Тут немного другая ситуация… Да и с extern-переменными в хедерах не так все просто…



0



ValeryS

Модератор

Эксперт по электронике

8809 / 6592 / 894

Регистрация: 14.02.2011

Сообщений: 23,182

29.08.2017, 12:12

6

Цитата
Сообщение от Байт
Посмотреть сообщение

Тут немного другая ситуация

ну да другая переменная объявлена сто раз

Цитата
Сообщение от Байт
Посмотреть сообщение

Да и с extern-переменными в хедерах не так все просто

а че там сложного
в одном Си файле

C++
1
int x;

в заголовочном

C++
1
extern int x;



1



40 / 21 / 3

Регистрация: 27.04.2015

Сообщений: 176

29.08.2017, 12:43

 [ТС]

7

Цитата
Сообщение от Байт
Посмотреть сообщение

Другой — вынести реализацию из хедера в CPP

Да действтельно вынес в cpp — заработало.

Цитата
Сообщение от ValeryS
Посмотреть сообщение

потому что Си файлы компилируются в разное время и при компиляции одного компилятор ничего не знает про другой
создаются куча объектных файлов не связанных друг с другом
а вот линковшик видит все объектные файлы и

Возникает другой вопрос, а почему тогда вынесение реализации в cpp файл не выдает ту же ошибку, ведь впринципе ничего не меняется?



0



Диссидент

Эксперт C

27499 / 17187 / 3784

Регистрация: 24.12.2010

Сообщений: 38,716

29.08.2017, 13:09

8

Цитата
Сообщение от elch10
Посмотреть сообщение

ведь впринципе ничего не меняется?

Еще как меняется! Прочитайте внимательно предыдущие посты в этой теме.



1



ValeryS

Модератор

Эксперт по электронике

8809 / 6592 / 894

Регистрация: 14.02.2011

Сообщений: 23,182

29.08.2017, 18:53

9

Лучший ответ Сообщение было отмечено elch10 как решение

Решение

Цитата
Сообщение от elch10
Посмотреть сообщение

ведь впринципе ничего не меняется?

очень даже меняется
макрос include просто подставляет текст заголовочного файла в Си файл
в результате в каждом Си файле есть

Цитата
Сообщение от elch10
Посмотреть сообщение

C++
1
2
3
4
bool isValidCoord(const Coord& c) 
{
 return true;
}

линкер видит стопитсот функций с именем isValidCoord и сходит с ума
а в случае реализации в Си файле функция только одна, в заголовочном только объявление функции а не реализация



2



Диссидент

Эксперт C

27499 / 17187 / 3784

Регистрация: 24.12.2010

Сообщений: 38,716

29.08.2017, 22:21

10

И придется повторить вопрос еще разок

Цитата
Сообщение от GbaLog-
Посмотреть сообщение

знаете, как директива препроцессора include работает?

А она работает чрезвычайно просто. Без всякой мистики.
Больше я этот вопрос повторять не намерен. Имеющий уши — да слышит! Имеющий хотя бы один глаз — да видит! Имеющий хоть капельку мозгов — да думает!



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

29.08.2017, 22:21

10

The multiple definition of C++ error appears when developers include a single function in two places. As a result, the program will define the functions twice, which is invalid when working with complex files, causing multiple definition errors.multiple definition of c

Although the solutions are not complicated and challenging to learn, debugging the error can be tedious due to the multiple definition of C++ header files. Therefore, this article answers the internet’s latest topics and questions regarding this annoying C++ error.

Contents

  • Why Is the Multiple Definition of C++ Error Happening?
    • – Using a Friend Function Displays the Error
    • – C++ Error Syntax Splitting Phases
  • How to Fix the Multiple Definition of C++ Error?
    • – Debugging the Error by Splitting the Syntaxes
  • Conclusion

Why Is the Multiple Definition of C++ Error Happening?

The multiple definition of C++ pragma once error happens when developers include the fun.cpp function in two places. For instance, programmers must not use CPP files when creating the function. Instead, they must use the header files that do not produce mistakes and affect other commands.

However, this is easier said than done because it is sometimes essential for programmers to include multiple definitions in a single document. Furthermore, this error mostly happens with less experienced users because they do not know how to replace the CPP files.

Furthermore, the multiple definition of C global variable affects similar functions inside a single document, corresponding with the definitions. Instead, our experts believe the header documents must have separate class definitions, and the CPP file must have the function definition.

This error occurs when programmers misplace the commands and include different values. For example, some developers keep the prototypes and descriptions in a single file, causing the system to display errors.

On the flip side, not linking the separate files appropriately will trigger the error and display it over your program. Therefore, separating the prototypes and definitions does not remove the error, which is annoying when working on complex files. So, the multiple definition of first defined here helps customers understand the detail. But first, we’ll discover the syntax that causes the bug.

– Using a Friend Function Displays the Error

Developers can encounter this error by including friend functions inside multiple definitions of X in C++, mixing the values and commands. However, this rookie mistake can sometimes destroy your user experience and prevent you from finishing the project.

In addition, the friend function interferes with the header documents and breaks the primary commands.Multiple Definition of C Causes

The following example includes the fun.cpp function with its good values:

// fun.cpp

#include <iostream>

using namespace std;

class classA {

friend void funct();

public:

classA(int a=1,int b=2):propa(a),propb(b){cout<<“constructorn”;}

private:

int propa;

int propb;

void outfun(){

cout<<“propa=”<<propa<<endl<<“propb=”<<propb<<endl;

}

};

void funct(){ // ERROR HERE

cout<<“enter funct”<<endl;

classA tmp(1,2);

tmp.outfun();

cout<<“exit funct”<<endl;

}

This is the code’s first part because developers must include a separate document for the main file.

Programmers can include as many or as few elements and values in the document, but we kept the syntax short and straightforward. Still, the concise code lines cause the error to appear without affecting other secondary functions.

Here is the second part of the code that displays the multiple definition of class C++ error:

// mainfile.cpp

#include <iostream>

#include “fun.cpp”

using namespace std;

int main(int nargin,char* varargin[]) {

cout<<“call funct”<<endl;

funct();

cout<<“exit main”<<endl;

return 0;

}

As you can see, this code completes the syntax and displays the error caused by declaring the friend function. But first, let us break down the error syntax to discover the three main processes and machine executables.

– C++ Error Syntax Splitting Phases

The previous syntax consists of two main parts, initiating three splitting phases that execute the machine code. Although all correct syntaxes include the same processes, the multiple commands of C++ error follow the basic principle but fail to compile the functions.

The first process is called preprocessing, where developers include macros and define the tasks that will get expanded. Fortunately, the multiple command error does not appear in the primary step, so that the program will complete the preprocessing efficiently.

The following step is called compiling because C++ implements the include function for the direct and indirect files. As a result, the program checks all parts by confirming if it can provide a single declaration for the commands.

Although developers can complete this function in the header documents, the program defines the functions in the CPP files. As a result, the program will correspond to functions defined in the CPP syntax and omit the commands without declarations.

The last step is called linking because the program matches declared links to where they belong. Therefore, the program will display an error if it comes across a function without declaration because it cannot reach a good place.

This is the step where C++ shows the multiple command error and ruins your programming experience. However, defining and debugging the issue is not complicated.

How to Fix the Multiple Definition of C++ Error?

Providing a separate class definition for the header and function definition for the CPP file is the most prolific solution to this standard error. However, our experts do not recommend including two fun.cpp functions in your document separately because the program defines the term twice.

As a result, C++ does not know which function to initiate first, causing the error to pop and stop your operations from working correctly. Although this is logical and does not usually happen with experienced users, making mistakes is natural.

Still, knowing how to react is critical because the program will not debug the error. Instead, developers must change the syntax and split the functions, which is not challenging or time-consuming.

Although our examples are different from your syntax, the principles are identical, so we recommend repeating our steps to avoid making errors. Therefore, you should not worry if your C++ document looks different. In addition, the fun.hpp function does not have many forms, so you can quickly recognize the similarities.

– Debugging the Error by Splitting the Syntaxes

Our experts recommend splitting the complete syntax into several parts to help you activate the functions and remove the error. For instance, creating different documents for the fun.hpp, fun.cpp, and mainfile.cpp functions would be best because you will not mistake the tags and elements.

In addition, our customers recommend avoiding using the namespace std function in header documents because it can confuse the program.Debugging the Error by Splitting the Syntaxes

This example shows the fun.hpp syntax and its functions, tags, and elements:

#include <iostream>

class classA {

friend void funct();

public:

classA(int a=1,int b=2):propa(a),propb(b){std::cout<<“constructorn”;}

private:

int propa;

int propb;

void outfun(){

std::cout<<“propa=”<<propa<<endl<<“propb=”<<propb<< std::endl;

}

};

The syntax in your document will be complete, but it will not affect your debugging setup. Next, we must separate the fun.cpp function in a different document, as shown in this example:

#include “fun.hpp”

using namespace std;

void funct(){

cout<<“enter funct”<<endl;

classA tmp(1,2);

tmp.outfun();

cout<<“exit funct”<<endl;

}

This example states the fun.hpp function in the header element, forming the path with the previous syntax without disturbing primary and secondary processes. In addition, the void function states the program’s purpose, which can be as long or short as you like.

The last part of the syntax requires developers to include the mainfile.cpp, as shown here:

#include <iostream>

#include “fun.hpp”

using namespace std;

int main(int nargin,char* varargin[]) {

cout<<“call funct”<<endl;

funct();

cout<<“exit main”<<endl;

return 0;

}

The C++ program will erase the error if you include this syntax in your document. So, this example shows nothing is impossible in working with C++.

Conclusion

The typical multiple commands of C++ error happen when developers and programmers include a single function in two places, confusing the system. Therefore, although we provided the error’s solution syntaxes and steps, this article also covered the following critical points:

  • Including a single function in two places means the C++ program will define the commands twice, which is incorrect
  • Typical CPP and HPP functions create this error because they contain the wrong elements
  • Your complete error syntax might be different, but the solution practice remains identical
  • The most refined way of fixing this error is creating separate documents with the HPP and CPP functions
  • This C++ error might affect parent and child elements and tags

Developers have dynamic experience working with C++ because it can display unexpected errors and bugs with seemingly correct documents. As a result, this guide debugged the error, provided the solution syntax, and taught you about C++ multiple command errors.

  • Author
  • Recent Posts

Position is Everything

Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team

Position is Everything

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
void display()
{
    scare_mouse();
    acquire_screen();
    clear_bitmap(buffer);
    clear_bitmap(buffer2);

    
    stretch_blit(background, buffer, scrollx, scrolly, background->w, background->h, 0, 0, int(background->w*scale), int(background ->h*scale));
     
    if(inP1A)
    {
        blit(C2BM1, buffer,0,0,int(mx+10),int(my+35),C2BM1->w,C2BM1->h); 
        if(mb);
    }
    if(inP1B)
    {
        blit(C2BM1, buffer,0,0,int(mx+10),int(my+35),C2BM1->w,C2BM1->h); 
        if(mb);
    }
    if(inP1C)
    {
        blit(C2BM1, buffer,0,0,int(mx+10),int(my+35),C2BM1->w,C2BM1->h); 
        if(mb);
    }
     
    if(TGridOn == true)
    {
        masked_stretch_blit(TGrid, buffer, scrollx, scrolly, TGrid->w,TGrid ->h,0,0, int(TGrid->w*scale), int(TGrid ->h*scale));
    }
    
    if(mx+int(scale*scrollx > 470) && mx+ int(scale*scrollx) < 510)
    {
        //textprintf_ex(buffer,font,1,200,WHITE,0, "X condition met");
        if(my+int(scale*scrolly) > 310 && my+int(scale*scrolly) < 350)
        {
            //textprintf_ex(buffer,font,1,220,WHITE,0, "X and Y conditions met");
            masked_stretch_blit(MTowerBS, buffer, 0,0,MTowerBS->w,MTowerBS ->h, int(228 - scrollx * scale), int(148 - scrolly * scale), int(MTowerBS->w*scale), int(MTowerBS ->h*scale));
        }
    }
    
    stretch_sprite(buffer, MTowerB, int(230 - scrollx * scale), int(150 - scrolly * scale), int(MTowerB->w*scale), int(MTowerB->h*scale)); 
    draw_sprite(buffer, MTowerB, int(320 - scrollx * scale), int(210 - scrolly * scale));
    
    masked_blit(backpanel, buffer2, 0, 0, 0, 0, backpanel->w-1, backpanel->h-1);
     
    
    /*                    Show this for testing purposes
    */
    textprintf_ex(buffer,font,1,5,WHITE,-1, "X on Screen: %d",mouse_x);
    textprintf_ex(buffer,font,1,15,WHITE,-1, "Y on Screen: %d",mouse_y);
    textprintf_ex(buffer,font,1,30,WHITE,-1, "X on Background: %d",int(Mx));
    textprintf_ex(buffer,font,1,40,WHITE,-1, "Y on Background: %d",int(My));
    textprintf_ex(buffer,font,1,65,WHITE,-1, "X: %d",scrollx);
    textprintf_ex(buffer,font,1,75,WHITE,-1, "Y: %d",scrolly);
    textprintf_ex(buffer,font,1,100,WHITE,-1, "Scale: %f",scale);
    
    textprintf_ex(buffer2,font,10,470,BLACK,-1, "Player 1 gold: %d",gold[0]);
    textprintf_ex(buffer2,font,10,480,BLACK,-1, "Player 2 gold: %d",gold[1]);
    
    p1A->setUpBoxes1(background, BLACK);
    
    
    pic1_x += 7;
    
    if(pic1_x < 550)
        stretch_blit(BPMB1,buffer,0,0,BPMB1->w,BPMB1->h,pic1_x,200,BPMB1->w,BPMB1->h);
    
    
    masked_blit(buffer2, screen, 0, 0, 0, 0, buffer2->w, buffer2->h);
    blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
    release_screen();
    
    show_mouse(screen);
    unscare_mouse();
}

void setXandY(double shcale)
{
    scale = shcale;
    if(shcale == 1)
    {
        maxX = 0;
        maxY = 38;
    }   
    else if(shcale == 1.5)
    {
        maxX = 58;
        maxY = 190;
    }
    else if(shcale == 2)
    {
        maxX = 168;
        maxY = 266;
    }
    else if(shcale == 3)
    {
        maxX = 277;
        maxY = 342;
    }
    else
    {
        maxX = 350;
        maxY = 450;
    }
    
    if(scrollx>maxX)
        scrollx = maxX;
    if(scrolly>maxY)
        scrolly = maxY;
    
    
}

PlatformIO Community

Loading

Понравилась статья? Поделить с друзьями:
  • Ошибка mudrunner msvcp140 dll
  • Ошибка net err cert authority invalid как исправить
  • Ошибка mtu xbox 360
  • Ошибка net err address unreachable
  • Ошибка mts rus 38