【问题标题】:multiple definition error when building C++ project with makefile [duplicate]使用makefile构建C ++项目时出现多个定义错误[重复]
【发布时间】:2019-03-17 00:59:10
【问题描述】:

在将其标记为已回答之前,请检查整个问题。

我是一个初学者并且自学编码,这个问题对于专业开发人员来说可能看起来很愚蠢,但除了在线社区之外我没有其他人可以帮助我。我尝试寻找答案,但没有找到具体的答案,因此我被困住了。

我正在创建一个简单的项目来学习使用 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.h中定义了一次vecsumi和n,它有文件保护,所以不能被包含两次。

非常感谢您对此的任何帮助。

【问题讨论】:

    标签: c++ makefile cmake


    【解决方案1】:

    变量的定义声明(vec、sum、i & n)应在实现文件(.cpp 文件)中完成,以避免编译器看到同一变量的多个定义。否则违反了称为 ODR(One Definition Rule) 的关键语言规则之一。

    由于您的两个 .cpp 文件(main.cpp 和 vec.cpp)都包含 vec.h 文件,因此通过翻译单元生成的目标文件将看到这些变量的多个定义(如果它们已在头文件中定义)。

    将变量定义从vec.h 移动到vec.cpp 文件,看看问题就消失了。

    为了进一步澄清,将以下行移至vec.cpp 文件。

    std::vector<int> vec;
    
    long long int sum;
    
    int i, n;
    

    【讨论】:

    • 如果其他代码文件需要访问,您忽略了头文件仍然需要声明。那看起来像extern long long int sum;
    • @ZanLynx 是的,但前提是他需要。根据示例,无需在标头中保留定义声明,因此无需使用extern。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多