为什么我的代码没有引发重复符号冲突

Why is my code not throwing a duplicate symbol conflict

为什么我的以下代码没有引发重复符号冲突?

我提到了名称修改,但这似乎只是在参数不同的情况下。但是,这里的参数没有区别。但是,它仍然不会引发冲突。为什么?

good.c

#include <stdio.h>

void printGood() {
    printf("I am good");
}

perfect.c

#include <stdio.h>

void printGood() {
    printf("I am perfect");
}

A.c

extern void printGood();

void bringGood() {
    printGood();
}

B.c

extern void printGood();

void bringPerfect() {
    printGood();
}

orchestrator.c

#include <stdio.h>

void bringGood();
void bringPerfect();

int main() {
    printf("bringing good");
    bringGood();
    printf("bringing perfect");
    bringPerfect();
    return 1;
}

编译行:

gcc -g -c good.c
gcc -g -c perfect.c

gcc -g -c A.c
gcc -g -c B.c

gcc -g -c orchestrator.c

ar rcs libA.a perfect.o A.o
ar rcs libB.a  good.o B.o

gcc -o orchestrator orchestrator.o -L.  -lA -lB

Why is my following code not throwing duplicate symbol conflict?

linker 按照在linker 行中指定的顺序在库中查找未定义的符号。当它在库中找到符号时,它会使用该定义并停止。它不检查该符号是否在 linker 行中指定的任何其他库中定义。

在你的例子中,如果 linker 在 A.lib 中找到一个符号,它就会停在那里。它不会在 B.lib.

中查找符号

根据您的命令,linker 将在库 A 的对象 perfect.o 中找到函数 printGood()。它不会使用库 Bgood.o 中的同名函数。所以你实际上 link orchestrator.oA.oB.operfect.o。这就是可执行程序打印 I am perfect 两次而不是 I am good.

的原因

仅当 linker 行中使用的对象文件包含多个定义时才会报告多个定义错误。

如果您使用:

,您将看到错误
gcc -o orchestrator orchestrator.o a.o b.o perfect.o good.o