Почему переопределение функции, которая уже присутствует в динамической или статической библиотеке, не выдает никакой ошибки?

Почему переопределение функции, уже присутствующей в динамической библиотеке, не приводит к ошибке компиляции и компоновки?

В функции ниже

#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 некоторые нелегальные коды требуют диагностики компилятора, а некоторые нет. Обычно те, которые не требуют диагностики, потому что:

  • было бы слишком непозволительно требовать от всех компиляторов обнаруживать и сообщать об ошибке
  • Существовали существующие системы, которые не диагностировали их, и Комитет по стандартизации не хотел, чтобы существующая реализация не соответствовала требованиям.

В этом случае, я думаю, что это случай первого; они хотели оставить открытой опцию для компиляторов / компоновщиков для реализации слабых символов как расширения, поэтому они не указали, что компилятор должен выдавать предупреждение здесь. Или, вообще-то, это вообще трудно обнаружить, я никогда не пытался написать компоновщик!

Это должно рассматриваться как вопрос качества реализации, если не проводится диагностика. Возможно, возможно передать различные флаги вашему компоновщику, чтобы он отклонил этот код; если нет, то вы можете поместить в отчет об ошибке или запрос функции.

Правильно ли вы связали разделяемую библиотеку, потому что компилятор должен выдавать ошибку:

множественное определение "среднее"

Другие вопросы по тегам