Problems with ....hmm, linker perhaps

P

Patrick Kowalzick

Dear all,

IMO the following program is legal and should compile.

//***** code start *********
// Definition of class A
template <typename T> struct A
{
typedef T value_type;
};

// Definition of class B
template <typename> struct B {};

// Function foo
// returntype important !
template <typename T>
B<typename T::value_type> foo()
{
return B<typename T::value_type>();
};

int main()
{
typedef B< int >( * ptr )(); // Function pointer

ptr foo_ptr = foo< A<int> >; // Initialization of function pointer

return 0;
}
//***** code end *********

It builds fine with g++ and MSVC7.1, but the latter one fails linking:

unresolved external symbol "struct B<int> __cdecl foo<struct A<int> >(void)"
(??$foo@U?$A@H@@@@YA?AU?$B@H@@XZ) referenced in function _main

what I do not really understand. It is getting a lit more weird now. If I
change

ptr foo_ptr = foo< A<int> >;

to

ptr foo_ptr ;
foo_ptr = foo< A<int> >;

it compiles and links fine as well with MSVC 7.1.

Before I blame anyone, I want to ask if I overlooked something? IMO the code
is fine.

Regards,
Patrick
 
J

JKop

If I change

ptr foo_ptr = foo< A<int> >;

to

ptr foo_ptr ;
foo_ptr = foo< A<int> >;

it compiles and links fine as well with MSVC 7.1.


Well, without scrutanizing your code too much, the only difference in the
above is that the former calls a constructor, while the latter calls the
default constructor and then calls operator=.


-JKop
 
T

Thomas Maier-Komor

Patrick said:
Dear all,

IMO the following program is legal and should compile.

//***** code start *********
// Definition of class A
template <typename T> struct A
{
typedef T value_type;
};

// Definition of class B
template <typename> struct B {};

// Function foo
// returntype important !
template <typename T>
B<typename T::value_type> foo()
{
return B<typename T::value_type>();
};

int main()
{
typedef B< int >( * ptr )(); // Function pointer

ptr foo_ptr = foo< A<int> >; // Initialization of function pointer

return 0;
}
//***** code end *********

It builds fine with g++ and MSVC7.1, but the latter one fails linking:

unresolved external symbol "struct B<int> __cdecl foo<struct A<int> >(void)"
(??$foo@U?$A@H@@@@YA?AU?$B@H@@XZ) referenced in function _main

what I do not really understand. It is getting a lit more weird now. If I
change

ptr foo_ptr = foo< A<int> >;

to

ptr foo_ptr ;
foo_ptr = foo< A<int> >;

it compiles and links fine as well with MSVC 7.1.

Before I blame anyone, I want to ask if I overlooked something? IMO the code
is fine.

Regards,
Patrick

compiles and links fine with Sun Studio 9...
 
U

Unforgiven

Patrick Kowalzick said:
Dear all,

IMO the following program is legal and should compile.

I concur with your opinion. I tested and verified that VC7.1 does not. I
think it's not a problem with the linker though, it looks as if the compiler
isn't instantiating the foo<A<int> > template, so when the linker looks for
it, it finds nothing.

I also tested this under Visual C++ 2005 (VC8) beta 1
(http://lab.msdn.microsoft.com/vs2005/), and it compiles and links fine,
which seems to suggest this is indeed a bug in VC7.1 which has been fixed
for VC8.
 
P

Patrick Kowalzick

Hi JKop,
Well, without scrutanizing your code too much, the only difference in the
above is that the former calls a constructor, while the latter calls the
default constructor and then calls operator=.

[answer for JKop]
Bullshit.

[answer for the rest]
I doubt that for function pointers constructors must be called. Is this
compiler dependent? Whats the terminology for built-in types?

Reagrds,
Patrick
 
P

Patrick Kowalzick

Dear Unforgiven,
I concur with your opinion. I tested and verified that VC7.1 does not. I
think it's not a problem with the linker though, it looks as if the compiler
isn't instantiating the foo<A<int> > template, so when the linker looks for
it, it finds nothing.

I also tested this under Visual C++ 2005 (VC8) beta 1
(http://lab.msdn.microsoft.com/vs2005/), and it compiles and links fine,
which seems to suggest this is indeed a bug in VC7.1 which has been fixed
for VC8.

Thanks a lot.

So it seems that I have to search a workaround for my application :(, which
has a little bit different structure compared to the testcase.

Patrick
 
J

JKop

[answer for JKop]
Bullshit.


Perhaps I should be more general:


A) AnyClass blah = some_expression;

This calls a contructor, supplying "some_expression" as an argument.


B) AnyClass blah; blah = some_expression;


This calls the default constructor. It then calls operator=.


Use your own intelligence to see what I'm getting at.


-JKop
 
P

Patrick Kowalzick

[answer for JKop]
Yep.


Perhaps I should be more general:


A) AnyClass blah = some_expression;

This calls a contructor, supplying "some_expression" as an argument.


B) AnyClass blah; blah = some_expression;


This calls the default constructor. It then calls operator=.

You are talking about classes, don't you?
See the OP, I was talking about function pointers.

Regards,
Patrick
 
R

Richard Herring

[QUOTE="JKop said:
[answer for JKop]
Bullshit.


Perhaps I should be more general:


A) AnyClass blah = some_expression;

This calls a contructor, supplying "some_expression" as an argument.


B) AnyClass blah; blah = some_expression;


This calls the default constructor. It then calls operator=.


Use your own intelligence to see what I'm getting at.
[/QUOTE]

What is the type of foo_ptr?
 
R

Rob Williscroft

Patrick Kowalzick wrote in in
comp.lang.c++:
int main()
{
typedef B< int >( * ptr )(); // Function pointer

ptr foo_ptr = foo< A<int> >; // Initialization of function pointer

return 0;
}
//***** code end *********

It builds fine with g++ and MSVC7.1, but the latter one fails linking:


_main

This is a bug in MSVC 7.1, Its "forgoten" to do the implicit
instantiation of foo< A< int > >.

I haven't seen it in precisly this context (taking a function pointer)
but in a few other's I have.

As a minor data point I compiled with:

cl -nologo -Za -Zc:forScope,wchar_t -EHsc -O1 -ML -Tptest.cpp

and msvc *didn't* exhibit the problem, but if I compiled:

cl test.cpp

I got the unresolved external, I don't know which combination of
option's achived this turnaround or why.

Rob.
 
A

Andrey Tarasevich

Patrick said:
...
int main()
{
typedef B< int >( * ptr )(); // Function pointer

ptr foo_ptr = foo< A<int> >; // Initialization of function pointer

return 0;
}
//***** code end *********

It builds fine with g++ and MSVC7.1, but the latter one fails linking:

unresolved external symbol "struct B<int> __cdecl foo<struct A<int> >(void)"
(??$foo@U?$A@H@@@@YA?AU?$B@H@@XZ) referenced in function _main
...

Seems to be a compiler problem. Try using the address-of operator explicitly

ptr foo_ptr = &foo< A<int> >;

I remember that sometimes it helped to solve similar problems in MSVC++
6, but I don't know whether it will help in MSVC++ 7.

Explicit instantiation will probably also solve the problem, but that
would be a high-maintenance solution.
 
R

Ron Natalie

There is a known bug in visual studio 6 when defining
function templates that don't have the templated variables
in their signature.
 
P

Patrick Kowalzick

Hi Andrey,
Seems to be a compiler problem. Try using the address-of operator explicitly

ptr foo_ptr = &foo< A<int> >;

same problem,...
I remember that sometimes it helped to solve similar problems in MSVC++
6, but I don't know whether it will help in MSVC++ 7.

Explicit instantiation will probably also solve the problem, but that
would be a high-maintenance solution.

but while I get around it like this:

ptr foo_ptr;
foo_ptr = &foo< A<int> >;

it is ok for now :). I documented in my code as a bug. Shall be enough....

Thanks,
Patrick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top