Как бороться с дублированным именем функции в C? - PullRequest
11 голосов
/ 23 июня 2010

У меня есть небольшой проект, в котором я назвал две одинаковые функции имени в двух разных исходных файлах, но во время сборки проекта произошел сбой компилятора с 'func_name, уже определенным в filename.obj'.

Почемуя не могу иметь две функции с одинаковыми именами в двух разных исходных файлах?Я думал, что функция должна быть локальной для исходного файла, только если, когда мы объявим ее в заголовочном файле, она станет глобальной.

И кроме изменения имени файла, есть ли другое элегантное решение для дублированного имени функции вязык программирования C?

Ответы [ 5 ]

34 голосов
/ 23 июня 2010

В C функция имеет глобальную область видимости по умолчанию. Чтобы ограничить его область, используйте ключевое слово static, чтобы сделать его закрытым для модуля.

Роль файла заголовка - просто опубликовать функцию вместе с ее подписью для других модулей.

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

Имена со статической и локальной областью действия должны быть уникальными только в пределах своей области.

8 голосов
/ 23 июня 2010

Независимо от того, объявлена ​​ли какая-либо вещь в заголовочном файле или в исходном файле, компилятор не имеет абсолютно никакого значения.Фактически, собственно компилятор абсолютно ничего не знает ни о каких «заголовочных файлах», поскольку заголовочные файлы внедряются в исходные файлы с помощью так называемого препроцессора , который выполняет свою работу до собственно компилятора.К тому времени, когда исходные файлы (со встроенными заголовочными файлами) попадают в фактический компилятор , уже невозможно определить, что было изначально и что было вставлено из заголовочных файлов.Исходный файл со всеми вложенными в него заголовочными файлами называется единица перевода .Т.е. правильный компилятор работает с единицами перевода, а не с некоторыми файлами «источника» или «заголовка».

На языке C все объекты и функции, объявленные в области видимости файла, имеют внешнюю связь по умолчанию,Это означает, что они являются глобальными, уникальными для всей программы.Итак, вы подумали неправильно.Функции не являются локальными только для одного исходного файла.

Если вы хотите сделать функцию (или объект) локальной для одной единицы перевода, вам нужно предпринять некоторые явные шаги.Вы должны объявить это как static.Объявление его как статического даст ему внутреннюю связь , что по сути означает, что оно становится внутренним по отношению к его единице перевода.

Объявление ваших функций static будет работать только в том случае, если им обоим действительно придетсябыть локальным для своих собственных переводческих подразделений.Если это не так, т. Е. Если хотя бы одна из функций должна быть глобально доступной (связываемой) функцией, то у вас нет другого выбора, кроме как переименовать одну из функций.

7 голосов
/ 23 июня 2010

Почему я не мог иметь две функции с одинаковым именем в двух разных исходных файлах?

Поскольку компоновщик должен знать, что имеется в виду, когда вы ссылаетесь на него.

Представьте, что a.h и b.h оба объявляют my_function(). Компилятор генерирует код для обоих. Теперь представьте, что c.c вызывает my_function() - как компоновщик узнает, какую из двух версий функции следует вызвать?

4 голосов
/ 23 июня 2010

Объявите функцию static, чтобы сделать ее локальной для файла.В C каждое имя идентификатора должно быть уникальным.

3 голосов
/ 23 июня 2010

Элегантным решением являются пространства имен, представленные в C ++.Решение, если имеется мало вызовов func_name, это взять один, переименовать его и перекомпилировать.

Что-то хакерское, но быстрое решение может быть таким:

//In one of the two source files and any file that calls it

//if your functions is something like this
//void func_name(int) { ... }
//Add the following line
#define func_name SOME_UNIQUE_FUNC_NAME
...