0

I'm experiencing a linking error with boost::lexical_cast for a static member variable that I don't understand.

Here's a small sample that demonstrates the problem (I know that it is silly, I could just << candy; but this demonstrates the problem I'm seeing in less trivial use of lexical_cast):

#include <iostream>
#include <boost/lexical_cast.hpp>

using namespace std;

class Test
{
public:
    void print_candy() const
    {
        cout << "candy is: " << boost::lexical_cast<string>(candy) << endl;
    }
private:
    static const unsigned int candy = 0;
};

int
main(int argc, char *argv[])
{
    Test t;
    t.print_candy();
    return 0;
}

This produces the following error when I compile it:

$ /opt/gcc-google-4.8/bin/g++ -Wall -I/usr/include --std=c++11 test.cc -o test
/tmp/cc9MV6cQ.o:test.cc:function Test::print_candy() const: error: undefined reference to 'Test::candy'
collect2: error: ld returned 1 exit status

Clearly candy is defined. If I remove the lexical cast and just redirect candy to out, the program compiles and links fine.

Some observations:

  • Making the member variable public does not remove the problem. That is, I still get the linker error with a public variable.
  • Making the member non-static does make the issue go away.
  • If I make a local variable that's a copy of the static one and pass that to the lexical_cast, it works fine.

So I'd like to understand:

  • Why is a static member variable coming up as undefined for lexical_cast?
  • What is the most elegant way to address this? I'd prefer not to remove static nor create an otherwise necessary local variable.
firebush
  • 5,180
  • 4
  • 34
  • 45
  • 2
    `candy` is not defined, you have a declaration with an initializer. Define it outside the class definition - `int const Test::candy;` – Praetorian Aug 25 '15 at 14:28
  • this compiles and links fine on coliru but fails also on my machine locally http://coliru.stacked-crooked.com/a/8d3773da965b90cb – Chris Beck Aug 25 '15 at 14:30
  • @Praetorian: thanks. I'll move the declarations outside the class in my case. Out of curiosity: why can the variable be used locally otherwise but not by lexical_cast? What about lexical_cast triggers the problem? – firebush Aug 25 '15 at 15:05
  • 1
    @firebush You're passing `candy` to `lexical_cast` by reference, which constitutes [odr-use](http://en.cppreference.com/w/cpp/language/definition#ODR-use) of that variable, so a definition is required. Surprisingly, neither gcc-5.1 nor VS2015 produce the same linker error, while clang does - http://coliru.stacked-crooked.com/a/a60795a022f562c4 I suspect some sort of optimization at play with the former two. – Praetorian Aug 25 '15 at 16:11

0 Answers0