|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
||||||||||||
Как получить undefined reference вместо вывода?10.08.2012, 11:18. Показов 1587. Ответов 8
Метки нет (Все метки)
Была ситуация - объявлен класс - в нем оператор приведения к некому типу (указатель на функцию), оператор вывода в поток для этого класса определен в другом хедере. Если забыть подключить сей хедер - он выводил 0 или 1 в зависимости от возвращаемого значения оператором приведения (можно довольно сильно влететь не подключив файл).
Сейчас - объявлен класс - в нем оператор приведения к некому типу (указатель на функцию), прямого оператора вывода в поток для этого класса нет, есть класс для вывода, но это к теме не относится, объявленный аналогично в другом хедере, соответственно проблема остается. А теперь вопрос.
0
|
||||||||||||
| 10.08.2012, 11:18 | |
|
Ответы с готовыми решениями:
8
Странная ошибка: [Linker error] undefined reference to `__dyn_tls_init_callback' [Linker error] undefined reference to ld returned 1 exit status Как исправить ошибку undefined reference to?
|
|
~ Эврика! ~
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
|
||||||
| 10.08.2012, 11:44 | ||||||
|
Я уж точно не помню, почему, но друзья шаблонных классов описываются вот так (19–20 строка). Но оно работает и не сыпет ошибками.
(чтоб не загромождать)
По идее дело в том, что каждый шаблонный класс — это отдельный класс. То есть нельзя объявить какую-то функцию другом сразу всех шаблонов, а надо тыкать носом в каждый из них (с помощью этого самого C<T>::). Ща пойду читать бумажку.
0
|
||||||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
|
| 10.08.2012, 11:46 [ТС] | |
|
~OhMyGodSoLong~, Да, это-то я вкурсе. Проблема в том, что этот код так же компилируется успешно, вместо того, чтобы давать undefined ref. http://liveworkspace.org/code/... 01dae8ace2
0
|
|
|
~ Эврика! ~
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
|
||||||
| 10.08.2012, 13:38 | ||||||
Сообщение было отмечено ForEveR как решение
Решение
Ну пока я вижу, что он вообще не трогает эту функцию, а почему-то берёт какую-то дефолтную. Потому, естессно, никаких undefined reference на неиспользуемую несуществующую функцию. Посмотрев ещё на это и немного потыкав это всё в отладчике, он почему-то делает неявный каст к unspecified_bool_type, который void (*)(), а потом почему-то... приводит его к bool O_O
Ниччё не понимаю... Ну ладно первый каст. Но второй-то почему? Ну ладно, не нашёл функцию с void (*)(), значит приводим дальше. Но почему тогда к bool, а не int? *яростно листает 13 главу про перегрузку* Объяснить ругань в случае (с friend std::ostream& operator << (std::ostream& os, unspecified_bool_type);) ещё можно: C<int>::unspecified_bool_type и C<float>::unspecified_bool_type — это разные типы; так как объявление использует unspecified_bool_type из объявляемого класса C<T>, то он влепил спецификатор C<T>::; но сама функция-друг не объявлена шаблонной (функции-друзья же не являются методами классов), потому не имеет права использовать шаблонный тип T. Добавлено через 46 минут (Ссылки привожу по этой версии.) Пример из 13.3.1.2/6
Итого, у компилятора, когда он видит запись std::cout << c;, то, так как никакого std::ostream& operator<<(std::ostream&, С<T>); нет, то возникает выбор между пачкой неявных преобразований: std::ostream& operator<<(std::ostream&, int); std::ostream& operator<<(std::ostream&, bool); std::ostream& operator<<(std::ostream&, С<T>::unspecified_bool_type); и т. д. В 13.3.3, 13.3.3.2 ногу свернуть можно. Но, по видимому, он не считает преобразование к С<T>::unspecified_bool_type достаточным, потому как метод не определён, поэтому продолжает искать другие цепочки, чтобы выбрать какую-нибудь другую альтернативную перегрузку. И находит цепочку C<T> → С<T>::unspecified_bool_type ≡ void (*)() → bool. Последнее это стандартное правило из 4.12: указатель можно кастовать к bool. (И, естессно, так как неопределённый метод при такой цепочке преобразований не используется, то линковщик на него и не ругается.) По-видимому, где-то так. Не по теме: В такие моменты прям отлично понимаешь, насколько C++ всё же монстр и сколько времени уходит на разработку его компиляторов.
1
|
||||||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
||
| 10.08.2012, 14:01 [ТС] | ||
0
|
||
|
~ Эврика! ~
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
|
||
| 10.08.2012, 15:02 | ||
Сообщение было отмечено ForEveR как решение
Решение
Вот потому и «по-видимому». Я точно не уверен в семантике подобной записи, когда есть прототип функции (то есть компилятор знает, как её вызывать, и по идее может использовать), но нет реализации. По идее, это головная боль линкера — отыскать код функции по всем файлам.
Но откуда тогда компилятор знает, что кода нет, и выбрает вместо преобразования к C<T>::unspecified_bool_type, для которого как бы нет кода, другое преобразование, которое дольше (и без чтения 13.3.3.2 можно понять, что каст к юзер-тайпу лучше, чем каст к юзер-тайпу, а потом ещё каст к стандартному). Откуда он знает, что его нет? Ведь действительно, если убрать шаблоны, то всё «не работает как надо». C → С::unspecified_bool_type ≡ void (*)() → bool не выбирается вместо C → С::unspecified_bool_type. Возможно, тут как-то замешан вот этот пункт 14.5.3/4
Попробуем проверить. Есть такой код, он не ругается и выбирает цепочку до bool. А теперь такой. И тут ничего... Тем более, что в 13.3.3.2 я что-то не увидел ничего про темплейты. Единственное, что смущает, это 13.3.3/1, второй список, второй пункт. Там сказано, что нешаблонное лучше шаблонного. Но это только при условии, что обе цепочки равны по «хорошести». Но есть ещё что-то в 13.3.3.1.2 про специальную трактовку юзер-кастов. Сейчас пытаюсь вкурить. Добавлено через 14 минут Что-то не разгорается. В общем, пока что я могу сделать вывод, что неявные преобразования типов — это одно из величайших зол, которое внесли в C++. Избавились от пары лишних строчек при «очевидных» преобразованиях, зато можно запросто повеситься в пустой комнате.
1
|
||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
|
| 10.08.2012, 15:50 [ТС] | |
|
~OhMyGodSoLong~, Ну да, теперь конечно есть explicit для user-defined conversions, но к сожалению нет возможности юзать С++11=(
Добавлено через 44 минуты Как-то я протупил и оказалось все на самом деле довольно просто... http://stackoverflow.com/quest... or-calling
1
|
|
|
~ Эврика! ~
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
|
|
| 10.08.2012, 15:57 | |
|
Ага... Выводилка типов у C++ не такая крутая. Теперь ясно, чего оно его не считает за валидный конечный вариант приведения (тупо не видит), но видит через цепочку до bool. И чего без темплейтов всё окей.
1
|
|
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
|
| 10.08.2012, 16:01 [ТС] | |
|
~OhMyGodSoLong~, Ну да. У меня впринципе сразу была такая мысль как только этот код написал, но казалось, что если не может определить тип - будет ошибка, а тут оказывается еще целая цепочка конвертирования. Вообщем, спасибо, много нового узнал)
0
|
|
| 10.08.2012, 16:01 | |
|
Помогаю со студенческими работами здесь
9
Undefined reference to Undefined reference Undefined reference to Undefined reference to undefined reference to Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога
Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
|
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
|
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога
В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
|
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
|
|
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога
Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
|
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
|
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования.
Часть библиотеки BedvitCOM
Использованы. . .
|
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога
SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
|