Почему переопределение функции, которая уже присутствует в динамической или статической библиотеке, не выдает никакой ошибки?
Почему переопределение функции, уже присутствующей в динамической библиотеке, не приводит к ошибке компиляции и компоновки?
В функции ниже
#include "calc_mean.h"
#include <stdio.h>
int mean(int t, int v) {
return 0;
}
int main () {
int theMean = mean(3,6);
printf("\n %d\n",theMean);
}
Внутри разделяемой библиотеки Определение средней функции уже присутствует, как показано ниже.
#include <stdio.h>
#include "calc_mean.h"
int mean(int a, int b) {
return (a+b)/2;
}
Определение средней функции уже присутствует в общей библиотеке libmean.so
, Но во время компиляции я не вижу ошибки переопределения, и компиляция прошла успешно.
И при успешном выполнении o/p, который я вижу, равен 0 вместо 4, поэтому определение функции среднего значения в разделяемой библиотеке не выполняется, а выполняется выполнение внутри основного модуля.
Почему так происходит?
3 ответа
Компоновщик связывает функцию только из библиотеки, если функция еще не была найдена в процессе компиляции / компоновки.
Причина различий в функциональности заключается в том, что существуют разные типы символов. Библиотечная функция является слабым символом. Он включается только в том случае, если он еще не определен. nm
инструмент для перечисления символов в объекте или исполняемом файле На его man-странице вы можете найти список типов символов.
Есть также страница википедии о слабых символах.
Наличие двух определений одной внешне видимой функции (даже если определения идентичны для не встроенных функций) приводит к неопределенному поведению, без диагностики. (Ссылка: C99 6.9#5 и Приложение J.2)
В C некоторые нелегальные коды требуют диагностики компилятора, а некоторые нет. Обычно те, которые не требуют диагностики, потому что:
- было бы слишком непозволительно требовать от всех компиляторов обнаруживать и сообщать об ошибке
- Существовали существующие системы, которые не диагностировали их, и Комитет по стандартизации не хотел, чтобы существующая реализация не соответствовала требованиям.
В этом случае, я думаю, что это случай первого; они хотели оставить открытой опцию для компиляторов / компоновщиков для реализации слабых символов как расширения, поэтому они не указали, что компилятор должен выдавать предупреждение здесь. Или, вообще-то, это вообще трудно обнаружить, я никогда не пытался написать компоновщик!
Это должно рассматриваться как вопрос качества реализации, если не проводится диагностика. Возможно, возможно передать различные флаги вашему компоновщику, чтобы он отклонил этот код; если нет, то вы можете поместить в отчет об ошибке или запрос функции.
Правильно ли вы связали разделяемую библиотеку, потому что компилятор должен выдавать ошибку:
множественное определение "среднее"