PDA

View Full Version : Linker error when using qMin(), qMax(), qBound()



zavulon
23rd September 2008, 14:18
Trying to use static const members in functions qMin(), qMax(), qBound() gives a linker error:
undefined reference to `<the static constant>'.

Here is an example code:


class Test
{
public:
static const float KValue=3.0;
Test();
};

Test::Test()
{
// Can be any function, not only a constructor
float foo = 1.0;
foo = qMax( foo, KValue );
}

int main()
{
// somewhere in a program
Test obj;
}


On the other hand, when using usual local constants, qMax (and friends) works ok:



float foo = 1.0;
const float value = KValue; // Make a copy of the static constant

foo = qMax( foo, value );


Please write, if someone knowswhy this happens or any good workarounds.

Sytem info:
Kubuntu 8.04
Qt 4.4.0 and 4.4.1
gcc 4.2.4

jpn
23rd September 2008, 14:34
You forgot something:


class Test
{
public:
static const float KValue;
Test();
};

const float Test::KValue=3.0; //<---

zavulon
23rd September 2008, 17:01
Year, right, thanks.
Static const float members are not allowed to be initialized within the class declaration.
But why did then the second variant work?

caduel
23rd September 2008, 17:57
The problem was not with qMax() etc but with your constant.
If you declare a class member (variable) as static, then you have to define it (outside of the class body). Otherwise the linker will complain.

In your second case, you did not define a static class member, so the linker was happy.

zavulon
23rd September 2008, 18:56
Nope, in my second example I keep using the same static const float. It's initialized inside the class and used very well inside the later code, but not in function qMax. I am already beginning to suspect that the error occurs because qMax() takes its arguments by reference (not value). Something wrong, when passing address of a static constant to a function.

Here is the same example 2, but at its full glory. It works, no error here:



class Test
{
public:
static const float KValue=3.0;
Test();
};

Test::Test()
{
// Can be any function, not only a constructor
float foo = 1.0;
const float value = KValue; // Make a copy of the static constant
foo = qMax( foo, value );
}

int main()
{
// somewhere in a program
Test obj;
}


I've also noticed the following facts:
* Changing from float to int doesn't change the situation a bit.
* Using "normal" functions that take arguments by value (not by reference) doesn't lead to the error. Such functions can easily take static constants as arguments.

caduel
23rd September 2008, 20:08
Probably the compiler optimizes your use of that "static const" away. (As it is static const, it is guaranteed to never change and can be replaced by its compile time value).
(Try without optimizations...)