Thread: linker error with static member...

  1. #1
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838

    linker error with static member...

    Code:
    class Binary
    {
        public:
            template<typename T>static void reverseBytes(T& input)
            {
                reverseBytes<sizeof(T)>((unsigned char*)&input);
            }
        private:
        
            static unsigned char holder;//LNK2020, LNK2001
            template<unsigned int N>inline static void reverseBytes(unsigned char* input)
            {
                holder = *input;
                *input=*(input+N-1);
                *(input+N-1)=holder;
                reverseBytes<N-2>(++input);
            }
            template<>inline static void reverseBytes<2>(unsigned char* input)
            {
                holder = *input;
                *input=*(input+1);
                *(input+1)=holder;
            }
            template<>inline static void reverseBytes<1>(unsigned char* input){}
    };
    Any ideas why does the line above generates unresolved token / unresolved external symbol errors in VS2k5?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Did you ever bother to do
    Code:
    unsigned char Binary::holder;
    anywhere? You need to do it exactly once.

  3. #3
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    odd. thanks.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, yes, one is an odd number, but I doubt that's where you were headed with that. You put an extern reference in your class (that's what static is -- it's not a member object since each member doesn't get its own), so you must have an actual object somewhere for that reference to refer to.

  5. #5
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    yes, it makes sense, it's just odd the compiler doesn't do it for you automagically if it's a primitive value or other value type with a default ctor.

    unfortunately, i've been out of the C++ world for a while; this is one of those bits of trivia that seems to have leaked out of my memory.

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    For when it comes up later, that code is not standard compliant.

    You need to move the specialization of template member functions of simple classes into the scope containing those classes. (For template classes, the enclosing template class itself must be specialized as well.)

    Further more, fully specialized function templates, even though they may look like function templates, are not templates. They are functions. They are treated, by the compiler and linker, as functions and not templates. In other words, the special behavior characterized by C++ compilers and linkers that allow multiple definitions for template functions will not be allowed for fully specialized template functions. Basically, this example would only work, if the specializations were moved outside the class definition, because you have marked them as `inline'; if you change that bit, you'll get multiple definition errors. In order to fix that, you'll have to treat them as you would any other function overload; you will declare them in a header and put the definition in a translation unit (a C++ source file).

    Finally, you have a bug; your code will find infinitely recursion and so compilers will refuse to compile.

    Soma

    Code:
    class Binary
    {
        public:
            template<typename T>static void reverseBytes(T& input)
            {
                reverseBytes<sizeof(T)>((unsigned char*)&input);
            }
        private:
        
            static unsigned char holder;//LNK2020, LNK2001
            template<unsigned int N>inline static void reverseBytes(unsigned char* input)
            {
                holder = *input;
                *input=*(input+N-1);
                *(input+N-1)=holder;
                reverseBytes<N-2>(++input);
            }
    };
            template<>inline void Binary::reverseBytes<2>(unsigned char* input)
            {
                holder = *input;
                *input=*(input+1);
                *(input+1)=holder;
            }
            template<>inline void Binary::reverseBytes<1>(unsigned char* input){}

  7. #7
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    to be honest, i didn't catch all of that.

    it ran just fine. it gave the same result as the looping implementation i am replacing...

    and i really don't care about std compliance. this is part of a C++/CLI project, so standardization is not a consideration.

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Okay.

    That's fine that you didn't catch it. Happily, the post is still there.

    Keep reading it until you do "catch it". Or at least ask a question about what you didn't get.

    it ran just fine.
    And you are using either the "MSVC" compiler or a couple of versions of the Intel compiler.

    Soma

  9. #9
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    yes, as in the OP, i'm using VS2k5. portability isn't a concern. thanks for the heads-up though.

  10. #10
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Yes, I knew what you were using; I was saying that you'd be limited to only those as it stands. If that isn't a problem, so be it.

    Soma

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by m37h0d View Post
    ...and i really don't care about std compliance. this is part of a C++/CLI project, so standardization is not a consideration...
    A dangerous thing to say. Don't come crying to us later when your code breaks.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. static declaration creates linker error
    By black_spot1984 in forum C++ Programming
    Replies: 1
    Last Post: 11-04-2008, 10:58 AM
  2. static instance variable linker error
    By animeaholic in forum C++ Programming
    Replies: 4
    Last Post: 01-23-2007, 09:50 PM
  3. non-static member error
    By noob2c in forum C++ Programming
    Replies: 14
    Last Post: 07-12-2003, 04:44 PM
  4. linker error, using static member
    By Chiel in forum C++ Programming
    Replies: 6
    Last Post: 06-28-2003, 08:40 PM
  5. help with static linkage error of member function
    By inandout in forum C++ Programming
    Replies: 2
    Last Post: 11-11-2002, 11:20 AM