Ошибка связана не с UNIX / Windows / любой другой ОС, а скорее с самими языками.На самом деле довольно просто диагностировать с помощью информации, которую предоставляют компиляторы.Обычно они сообщают вам, какой символ отсутствует, а иногда и где он используется.Основные причины пропуска символа:
- Вы объявили, но никогда не определяли его
- Вы определили его, но не добавили скомпилированный символ (объектный файл / библиотека) к компоновщику
- Он является внешним, и вы забыли связать библиотеку, либо вы ссылаетесь на неверную версию, либо в неправильном порядке.
Первый вариант немногохитрее, если вы намеревались определить символ, но не соответствовали объявлению (объявлено void foo( int, double );
, но определено void foo( double, int )
. Как и во всех других случаях, компилятор сообщит вам точную подпись, которую ищетдля, убедитесь, что вы определили , что символ , а не что-то близкое или похожее, может быть конкретным угловым случаем, если вы используете разные соглашения о вызовах в объявлении и определении, так как они будут выглядеть очень похожев коде.
В случае внешнего кода библиотек сложность состоит в том, чтобы определить, какую библиотеку необходимо связать для добавления этого символа.Эд, и это происходит из документации библиотеки.Помните, что со статическими библиотеками порядок библиотек в командной строке компоновщика влияет на результат.
Чтобы помочь вам определить, какие символы на самом деле определены, вы можете использовать nm
(gcc, который распространен среди систем Unix).Таким образом, вы можете запустить nm
для объектных файлов / библиотек, на которые вы ссылаетесь, и найти символ, на который жалуется компоновщик.Это поможет в тех случаях, когда порядок - это то, что имеет значение (т. Е. Символ есть, но компоновщик его пропустил).
Во время выполнения (спасибо Matthieu M. за указание на это) у вас могут быть похожиепроблемы с динамическими библиотеками, если в LD_LIBRARY_PATH найдена неправильная версия библиотеки, вы можете получить библиотеку, в которой нет необходимого символа.