Skip to main content
gamedev.net
🔒 Locked

Adding a function call to a constructor causes linker errors :/

Started by civguy Nov 23, 2001 at 8:23 PM 9 replies 900+ views
Original Post
civguy
civguy
(I''m using VC++ 6.0) I have a base class with a couple of virtual functions. The constructor looks like this
  
template <typename stateInfo, typename maskType>
baseSolver<stateInfo, maskType>::baseSolver()
{
storageAmount=0;
initVisit=false;
}
  
Everything works well so far. Now, when I add any function call in that constructor, for example:
  
template <typename stateInfo, typename maskType>
baseSolver<stateInfo, maskType>::baseSolver()
{
storageAmount=0;
initVisit=false;
printf("Woohoo\n");
}
  
I get a bunch of linker errors: main.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall baseSolver::showMapTile(class Vector2d const &,struct binkyStateInfo const &)" Similar errors for each of my virtual functions.. I have defined the functions in the inherited classes and everything works fine until I add a function call to the constructor of the base class. Function calls in the constructors of the inherited classes work fine. Also, adding a destructor for the base class gives the same result (I even tried adding a virtual destructor). I''m new with templates and virtual functions so it might be some very simple mistake.. But I''ve spent long enough to find it with no luck :/. So thanks a lot in advance if you know how to fix this.
Null and Void
Null and Void
It is a ''bug'' in MSVC (and some other compilers, as I''m sure someone will point out if I fail to mentio it) that you have to have place the entire template inside of one file (probably a header). I''m not sure if any compilers support seperation of templates, but I''ve heard the BCB does (I don''t own it, so I can''t test it).

[Resist Windows XP''s Invasive Production Activation Technology!]
Shannon Barber
Shannon Barber
Make sure you''ve including the appro. header files.

Template functions need to be declared in the header or inline.
Some compilers pull tricks to allow you to put template code in .cpp file, but this is non-standard behavior.

It''s also a HUGE no-no to call virtual functions in constructors. I can all but garuantee it won''t behave the way you want it too.

The MSVC compiler and linker don''t handle template syntax error gracefully. Things compile that shouldn''t. Incremental linking often fails. Whenever you get funky template errors that seems elusive, try a full re-build - even delete the ''Debug'' directory.

If the error persist, it''s probably really and error. Thank your stars MSVC actually noticed

The only time a constructor is invoked, is when you declare an object instance (on the stack) or allocat one with new.

Magmai Kai Holmlor
- Not For Rent
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
merlin9x9
merlin9x9
If I''m not mistaken, doesn''t that functionality (implementing templates outside of header files and/or in separate files) require the use of the export keyword which, of course, VC++ doesn''t support?

I''d sure like to see a compiler that''s 100% standard-compliant...
Cyberdrek
Cyberdrek
quote:
Original post by merlin9x9
If I''m not mistaken, doesn''t that functionality (implementing templates outside of header files and/or in separate files) require the use of the export keyword which, of course, VC++ doesn''t support?

I''d sure like to see a compiler that''s 100% standard-compliant...


I''m not 100% sure but I think Digital Mars C++ ( if you prefer, the old Zortec C++ compiler, later bought by Symantec and now back in the hands of the creator of Zortec C++ ) allows it. Not sure though...



"And that''s the bottom line cause I said so!"

Cyberdrek
Headhunter Soft
A division of DLC Multimedia

Resist Windows XP''s Invasive Production Activation Technology!

"gitty up" -- Kramer
[Cyberdrek | ]
Shannon Barber
Shannon Barber
quote:

It is a 'bug' in MSVC ... that you have to have place the entire template inside of one file


Strictly speaking that statement is completely false. You can put whatever you want where-ever you want with C/C++. Convention tells you to put declarations in so-called header files and defintions in so-call source files. The template header, fstream, draws upon code in iostream, and is an example of template code in multiple files.

Now, what I think you meant was that some compilers allow you put template defintions in source files but MSVC does not. That is entirely true - but also a bizarre thing to do if you reflect upon the nature of templates.

You may also have been refering to the problems MSVC has with template method and nested template class defintions. Which by all means you should be able to define outside of the parent class but often cannot - but still should not be defined in cpp files.

How many source files do you add to your project and how many libraries do you link to use the STL? ZERO-NONE-NADA-ZILCH!!!
(well somtimes they sneak one in for constants, static functions, and some other conventional code, but none are for the templates themselves.)

In fact the extention .h doesn't even make a hell-of-a-lot of sense for templates. I used .hpp when I first starting working with C++, and I continue to do so, but the _standard approach is to eliminate the extention entirely!


I suppose "non-standard" isn't the right term to use, as The standard has provisions for the export keyword, but I know of no compilers that implement it to the letter of The standard. Though some are better than "others" (meaning of course MSVC).

Magmai Kai Holmlor
- Not For Rent

Edited by - Magmai Kai Holmlor on November 23, 2001 10:04:58 PM
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Null and Void
Null and Void
Magmai Kai Holmlor, I think you knew what I meant . If you want to use a template class in more than one file you''ll have to put the class in a header (as is natural). Now, you''re suppossed to be able to put the function bodies within a seperate (but linked) source file (as was said, using the export keyword). However, MSVC won''t allow you to do that (see previous disclaimer) since it doesn''t support the export keyword.


[Resist Windows XP''s Invasive Production Activation Technology!]
Shannon Barber
Shannon Barber
The whole reason you need to use the export keyword is _because that "template source file" isn''t directly linked. Eventually incarnations of it are linked, but that "source" file isn''t.

What''s really need is a seperate naming covention and project settings for template code; I suppose that''s what the absense of an extention and export keyword are for.... if only more than two compilers support it
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
civguy
civguy
Thanks for the help, I got the problem solved. After what you said, I thought the compiler might be giving wrong errors or something so I started making the problem smaller and smaller. It appeared that my virtual functions didn''t have any procedures defined in the base class (I didn''t know they needed to have one). They used to simply look like this (with no definitions anywhere):

virtual mybool isSameState(stateInfo &a, stateInfo &b);

So I changed them to

virtual mybool isSameState(stateInfo &a, stateInfo &b)=0;

And everything started working.

(I bet you''ll all be groaning and moaning that I had such a dumb mistake there )
Shannon Barber
Shannon Barber
quote:

It appeared that my virtual functions didn't have any procedures defined in the base class (I didn't know they needed to have one).


This is a strong indication of BSA (bad @#$% afoot).
Are you calling those functions in a constructor?
Did you make them pure virtual functions?

    
template<typename T>
class Base
{
virtual T MyVirtualMethod(); //Need a base definition

virtual T MyPureVirtualMethod()=0; //Want you really want

};


Magmai Kai Holmlor
- Not For Rent

[edit explenitive deleted]

Edited by - Magmai Kai Holmlor on November 24, 2001 12:56:19 PM
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
civguy
civguy
Nope, I didn''t call them in the constructor. Adding any function call to the constructor caused the linker errors (eg. printf). Which was probably some really weird MSVC bug.

But yea, I made them pure and it fixed the problem.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.