使用makefile构建C ++项目时出现多定义错误

时间:2019-03-17 00:59:11

标签: c++ makefile cmake

在标记为已回答之前,请仔细阅读整个问题。

我是一个初学者,我自己一个人学习编码,这个问题对于专家开发人员来说似乎很愚蠢,但是除了在线社区以外,我没有其他人可以帮助我。我尝试搜索答案,但由于遇到问题,没有找到具体答案。

我正在创建一个用于学习使用make文件的简单项目,并且不断收到多个定义错误。

下面是 Makefile

的代码
all: vecy

vecy: main1.o vec.o
    g++ -o vecy main1.o vec.o

main1.o: main1.cpp vec.h
    g++ -c main1.cpp

vec.o: vec.cpp vec.h
    g++ -c vec.cpp

.PHONY: clean
clean:
    rm -f *.o vecy

下面是我执行Makefile时遇到的 Errors

g++ -o vecy main1.o vec.o
vec.o:(.bss+0x0): multiple definition of `vec'
main1.o:(.bss+0x0): first defined here
vec.o:(.bss+0x18): multiple definition of `sum'
main1.o:(.bss+0x18): first defined here
vec.o:(.bss+0x20): multiple definition of `i'
main1.o:(.bss+0x20): first defined here
vec.o:(.bss+0x24): multiple definition of `n'
main1.o:(.bss+0x24): first defined here
collect2: error: ld returned 1 exit status
Makefile:4: recipe for target 'vecy' failed
make: *** [vecy] Error 1

下面是 main1.cpp

的代码
#include <iostream>
#include "vec.h"

int main(){
input();
print();
}

下面是 vec.h

的代码
#include <vector>

#ifndef vec_h
#define vec_h

std::vector<int> vec;

long long int sum;

int i, n;

void input();
void print();

#endif

下面是 vec.cpp

的代码
#include <iostream>
#include "vec.h"

using namespace std;

void input(){

cout << "Enter the number of elements you want to enter into the vector = ";
cin >> n;

for (i = 1; i <= n; i++){
int alpha;  cin >> alpha;
sum += alpha;
vec.push_back(alpha);
}
}

void print(){

cout << "elements entered into the vector are\n\n";

for (i = 0; i < n; i++){
    cout << vec[i] << "  ";
}
cout << endl;
cout << "Sum of elements entered in the vector = " << sum << endl;

}

问题出在哪里?我仅在头文件vec中定义了sum i nvec.h一次,并且该文件具有适当的文件保护措施,因此不能被包含两次。

非常感谢您提供任何帮助。

2 个答案:

答案 0 :(得分:1)

变量(vecsumin的定义声明应在实现文件(.cpp文件)中完成,以避免编译器看到同一个变量的多个定义。否则,就会违反一种关键语言规则,即ODR(一个定义规则)。

由于两个.cpp文件(main.cppvec.cpp)都包含vec.h文件,因此,通过转换单元生成的目标文件将在定义了这些变量的情况下看到多个定义在头文件中。

将变量定义从vec.h移到vec.cpp文件中,看问题已解决。

为进一步说明,请将以下行移至vec.cpp文件。

std::vector<int> vec;

long long int sum;

int i, n;

答案 1 :(得分:0)

您已经在头文件中定义了对象,这些对象包含在两个源文件中。但是,ODR规则意味着不允许您在单个转换单元中对不同的对象重复使用相同的名称,因此会出现多定义错误。

解决方案:不要在头文件中定义对象,而是将其移动到源文件中。