Название: Ошибка компоновщика при использовании qMin(), qMax(), qBound() Отправлено: zavulon от Сентябрь 23, 2008, 15:30 Попытка использовать статические константы-члены в функциях qMin(), qMax(), qBound() выдает следющую ошибку компоновщика:
undefined reference to `<статическая константа>'. Вот пример кода: Код: class Test С другой стороны, при использовании обычных локальных констант в qMax (и подобных) всё проходит отлично. Пример нормальной работы: Код: float foo = 1.0; Напишите, если кто знает из-за чего это происходит. Используемая платформа: Kubuntu 8.04 Qt 4.4.0 and 4.4.1 gcc 4.2.4 Название: Re: Ошибка компоновщика при использовании qMin(), qMax(), qBound() Отправлено: pastor от Сентябрь 23, 2008, 15:55 qMin(), qMax(), qBound() здесь непричем. Вы пытаетесь инициализировать значением статический константный неинтегральный тип, а так делать нельзя. Только статические константные интегральные типы могут инициализироваться значением внутри класса.
Т.е. нужно писать так: Код: class Test Название: Re: Ошибка компоновщика при использовании qMin(), qMax(), qBound() Отправлено: zavulon от Сентябрь 23, 2008, 17:25 Огромное спасибо!
Действительно, в C++ простые типы данных делятся на две группы: целые (интегральные, integral) и нецелые. Целые типы имеют конечный и заранее известный набор значений: int, char, short, long и перечисления (enumerations). Все остальные, например float, double, char[], - это нецелые типы. Вообще, в C++ в заголовке класса можно только объявлять статические константы. Опеределять их значение нужно уже вне объявления класса - как правило это .cpp - файл. Единственное исключение делается для целых (интегральных) типов - такие статические константы можно инициализировать сразу же при объявлении внутри класса. http://www.informit.com/blogs/blog.aspx?uk=30-C-Tips-in-30-Days-Tip-26-in-class-initialization-of-const-static-data-members-of-integral-types (http://www.informit.com/blogs/blog.aspx?uk=30-C-Tips-in-30-Days-Tip-26-in-class-initialization-of-const-static-data-members-of-integral-types). Поэтому, в данном случае с типом float не было так гладко. Но остается загадкой, почему мой второй вариант кода тогда работал? Т.е. когда static const float инициализируется внутри класса, а потом в каком-нибудь методе значение такой константы можно присвоить локальной переменной. Название: Re: Ошибка компоновщика при использовании qMin(), qMax(), qBound() Отправлено: zavulon от Сентябрь 23, 2008, 19:41 Становится все более интересно. Если float заменить на int, ничего не меняется. Компоновщик выдает ту же ошибку уже для целого типа.
Функции qMax() и др. реализованы как шаблоны, а аргументы передаются с помощью ссылок: Код: template<class T> Если эту же константу передать в любую другую Qt-функцию, которая берет в качестве аргумента именно int или float (т.е. по значению), то все прекрасно работает. Пример рабочего кода: Код: #include <QList> Название: Re: Ошибка компоновщика при использовании qMin(), qMax(), qBound() Отправлено: pastor от Сентябрь 23, 2008, 20:15 Приведите полное сообщение об ошибке
//upd Проверил код на MSVC2005, все работает нормально. Позже проверю под Линуксом Название: Re: Ошибка компоновщика при использовании qMin(), qMax(), qBound() Отправлено: Alex03 от Сентябрь 24, 2008, 07:36 А у меня вот тут вопрос возник...
А чем отличаются в данном случае статическая и не статическая константы? В случае: Код: class Test Да и вообще есть ли точные правила когда константа обязательно представленна ячейкой памяти (и соответственно имеет свой адрес и т.д.), а когда может быть полностью соптипизированна (на той же x86 платформе тот же int проще константой в коде иметь, чем вытаскивать по адресу, порой ещё и не прямому). Всё... пора идти за страуструпом (книга между домом и работой уже наверное месяц катается без дела). Название: Re: Ошибка компоновщика при использовании qMin(), qMax(), qBound() Отправлено: zavulon от Сентябрь 25, 2008, 16:29 Я пришел к выводу, что ошибка вызвана оптимизацией компилятора. Компилятор все константы, если это возможно, заменяет на числовые значения, которые естественно не имеют своего адреса. Попытка взять адрес такой константы в функции qMax(), приводит к ошибке. qMax(), qMin() и qBound() принимают аргументы по ссылке, а не по значению.
|