В соответствии с ISO C программа вызывает неопределенное поведение. Используемое внешнее имя должно иметь в программе ровно одно определение. *
«Слабые символы» - это понятие в некоторых динамических библиотечных системах, таких как ELF в GNU / Linux. Эта терминология здесь не применима. Говорят, что компоновщик, который допускает множественные определения внешнего символа, реализует модель «смягченный ref / def». Этот термин взят из раздела 6.1.2.2 Обоснование ANSI .
Если мы рассматриваем смягченную модель ref / def как документированное расширение языка, то множественные определения имени становятся локально определенным поведением. Тем не менее, что, если они неправильно напечатаны? Это почти наверняка не определено из-за того, что ситуация напоминает псевдоним псевдонимов. Возможно, что если один модуль имеет int x; int y;
, а другой - double x
, то запись через псевдоним double x
приведет к засорению y
. На это нельзя положиться. Это очень плохой способ получить эффект псевдонима специально; Вы хотите использовать union
между двумя структурами или чем-то подобным.
Теперь о «слабых символах»: это внешние имена в общих библиотеках, которые могут быть переопределены альтернативными определениями. Например, большинство функций в библиотеке GNU C в системе GNU / Linux являются слабыми символами. Например, программа может определить свою собственную функцию read
для замены функции POSIX. Сама библиотека не сломается, независимо от того, как переопределено read
; когда ему нужно вызвать read
, он не использует слабый символ read
, но некоторые внутренние псевдонимы, такие как __libc_read
.
Этот механизм важен; это позволяет библиотеке соответствовать ISO C. В строго соответствующей программе ISO C разрешается использовать read
в качестве внешнего имени.
* В стандарте ISO C99 это было дано в 6.9 Внешние определения : "Если идентификатор, объявленный с внешней связью, используется в выражении (отличном от части операнда оператор sizeof, результатом которого является целочисленная константа), где-то во всей программе должно быть ровно одно внешнее определение для идентификатора, в противном случае должно быть не более одного. "