Чтобы разрешить несколько определений, мы должны требовать, чтобы определение было функционально идентичным - в противном случае у вас должен быть какой-то способ решить, какой запускать, и в этот момент вы могли бы также дать им разные имена.
ПроверкаТо, что два определения функций идентичны, является нетривиальной проблемой.Поскольку функции могут быть объявлены в нескольких единицах перевода, вам необходимо сравнить их на этапе соединения, чтобы доказать, что они идентичны.Это проблема, когда вы начинаете заниматься оптимизацией компилятора, которая может учитывать другое содержимое этих модулей перевода.Например, рассмотрим:
const char *foo() {
return "world";
}
Достаточно просто, верно?Теперь мы скомпилируем два файла.a.c
содержит только foo
.b.c
также содержит это:
const char *bar() {
return "Hello world";
}
Компилятор может сделать так, чтобы foo()
'world' указывал на середину bar()
'Hello world'.Линкер должен каким-то образом определить, что два foo()
идентичны, даже если они указывают на неидентичные константные данные.
При рассмотрении правил наложения имен возникает большая проблема.Рассмотрим:
void frob(int *p);
int foo() {
int x = 1;
x++;
frob(&x);
}
Скомпилировано само по себе, это может привести к тому, что ассемблерный код будет похож на:
foo:
sub %esp, 4 ; allocate stack space for x
mov dword [%esp], 2 ; set x to 2 (x++ combined with initialization)
push %esp ; push %x to the stack as frob's argument
call frob
mov %eax, dword [%esp+4] ; load the value of x into eax for the return value
add %esp, 8 ; clear the stack of frob's argument and x
ret ; return
Теперь давайте скомпилируем его с определением frob
в области действия:
void frob(int *p) { /* no-op */ }
Теперь у нас есть:
frob:
ret ; return
foo:
mov %eax, 2 ; return value = 2
ret ; return
Как компоновщик может сказать, что два foo
определения идентичны?
Учитывая трудности с доказательством идентичности тел функций, C выбираетпросто запретить вам определять одну и ту же функцию дважды.C ++ использует другой подход для встроенных и шаблонных функций;он просто не проверяет и предполагает, что они идентичны.
Что касается объявлений, с другой стороны, существуют определенные правила для проверки совместимости, поэтому нет проблем с разрешением нескольких совместимых объявлений.