Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, March 2002
AW: Visual C++ 7 sucks


Message 1 in thread

The problem in your case is that VC++ 7 doesn't support class template
instantiation across DLL boundaries which shouldn't be possible anyway
according to the ANSI standard because template class declarations have to
be included together with their member function implementations to make it
possible to specialize on the required datatypes at compiletime (that's what
templates essentially do). The core problem is that Trolltech uses the
Q_EXPORT (expands to '__declspec(dllexport)') macro on class templates, too.
VC++ 6 seemingly ignored this and specialized from the implementations of
the header file anyway but VC++ 7 wants to get the template specialization
from the dll in this case. If you want to use a QValueList using VC++ 7 it
helps to remove the Q_EXPORT macros from the qvaluelist.h file but
unfortunately this does not work when you try to use a Qt class which
inherits from QValueList such as QStringList and is not a template class by
itself and therefore lives as compiled code within the Qt DLL. In this case
the VC++ 7 compiler always searches for exports of the specialized member
functions from QValueList within the Qt DLL.
To sum it up: Trolltech should at least be able to solve this on their own.
Tell me if I'm wrong.

Tom


-----Ursprüngliche Nachricht-----
Von: Craig Black [mailto:cblack@ara.com]
Gesendet: Freitag, 01. März 2002 16:59
An: qt-list
Betreff: Visual C++ 7 sucks


Visual C++ 7 compiler is broken and unusable. It's not even as good as 6.
I'm getting link errors when instantiating simple templates like QValueList.
I think they broke it on purpose to move people away from C++ to the new
.net stuff.
Does anyone have any suggestions/comments?

--
 [ signature omitted ] 

Message 2 in thread

> The problem in your case is that VC++ 7 doesn't support class template
> instantiation across DLL boundaries which shouldn't be possible anyway
> according to the ANSI standard because template class declarations
have to
> be included together with their member function implementations to
make it
> possible to specialize on the required datatypes at compiletime
(that's what
> templates essentially do). The core problem is that Trolltech uses the
> Q_EXPORT (expands to '__declspec(dllexport)') macro on class
templates, too.
> VC++ 6 seemingly ignored this and specialized from the implementations
of
> the header file anyway but VC++ 7 wants to get the template
specialization
> >from the dll in this case. If you want to use a QValueList using VC++
7 it
> helps to remove the Q_EXPORT macros from the qvaluelist.h file but
> unfortunately this does not work when you try to use a Qt class which
> inherits from QValueList such as QStringList and is not a template
class by
> itself and therefore lives as compiled code within the Qt DLL. In this
case
> the VC++ 7 compiler always searches for exports of the specialized
member
> functions from QValueList within the Qt DLL.
> To sum it up: Trolltech should at least be able to solve this on their
own.
> Tell me if I'm wrong.
>
> Tom
>

You're wrong ;-)
I tried that already, and it fixes the compilation bug. The problem
however is that Qt itself uses instances of those templates as class
members of Q_EXPORT'ed classes. Those instances we have to explicitely
declare as Q_EXPORT'ed classes, too. You see a lot

#if defined(Q_TEMPLATEDLL)
template class Q_EXPORT QDict<foo>;
#endif

in Qt, which avoids warnings like "qdockarea.h(102) : warning C4251:
'ls' :
class 'QPtrList<class QDockWindow>' needs to have dll-interface to be
used by
clients of class 'QDockAreaLayout'"

If we ignore this warning we get crashes due to memory allocation errors
when running Qt. If we don't ignore it, we get unresolved symbols
(independently from us using Q_EXPORT in the template class declaration
itself).

Also note that __declspec(dllexport) is a hint to the compiler to
implement a new/delete operator for that class that can be transparently
used accross DLL boundaries (not talking about the fact that you can't
use QStringList anymore...)

So the bottomline for me is that Microsoft broke their compiler without
any need to do so in the first place, so they should fix it. I have
tried to work around the issue, but it's not possible without rewriting
big parts of Qt, and probably not without possibly breaking compilation
for VC++ 6.0 (Borland C++ etc).

--
 [ signature omitted ] 

Message 3 in thread

Well... I didn't say that VC++ 7 doesn't suck ;-)

hmm.. considering your mail it really seems to be MS's fault. So it's
because they removed the ability to import already instantiated template
specializations from DLL's without an obvious reason... except maybe one: if
the implementation in the template header file differs from the one compiled
version in the DLL (because the DLL has been compiled with a different
implementation of the template class) the compiler wouldn't know which one
to use (what probably could be ignored if the interfaces are the same and
the compiled version is not broken).

Tom

-----Ursprüngliche Nachricht-----
Von: Volker Hilsheimer [mailto:vohi@gmx.de]
Gesendet: Montag, 04. März 2002 12:17
An: qt-interest@trolltech.com
Betreff: Re: Visual C++ 7 sucks
You're wrong ;-)
I tried that already, and it fixes the compilation bug. The problem
however is that Qt itself uses instances of those templates as class
members of Q_EXPORT'ed classes. Those instances we have to explicitely
declare as Q_EXPORT'ed classes, too. You see a lot

#if defined(Q_TEMPLATEDLL)
template class Q_EXPORT QDict<foo>;
#endif

in Qt, which avoids warnings like "qdockarea.h(102) : warning C4251:
'ls' :
class 'QPtrList<class QDockWindow>' needs to have dll-interface to be
used by
clients of class 'QDockAreaLayout'"

If we ignore this warning we get crashes due to memory allocation errors
when running Qt. If we don't ignore it, we get unresolved symbols
(independently from us using Q_EXPORT in the template class declaration
itself).

Also note that __declspec(dllexport) is a hint to the compiler to
implement a new/delete operator for that class that can be transparently
used accross DLL boundaries (not talking about the fact that you can't
use QStringList anymore...)

So the bottomline for me is that Microsoft broke their compiler without
any need to do so in the first place, so they should fix it. I have
tried to work around the issue, but it's not possible without rewriting
big parts of Qt, and probably not without possibly breaking compilation
for VC++ 6.0 (Borland C++ etc).

--
 [ signature omitted ] 

Message 4 in thread

> Well... I didn't say that VC++ 7 doesn't suck ;-)
>
> hmm.. considering your mail it really seems to be MS's fault. So it's
> because they removed the ability to import already instantiated
template
> specializations from DLL's without an obvious reason... except maybe
one: if
> the implementation in the template header file differs from the one
compiled
> version in the DLL (because the DLL has been compiled with a different
> implementation of the template class) the compiler wouldn't know which
one
> to use (what probably could be ignored if the interfaces are the same
and
> the compiled version is not broken).
>
> Tom

Yes, that's also a bug in the VC++ compiler. If you have an indentical
template instantiation both in the DLL and in your application you might
end up with linker trouble and have to add /FORCE:multiple to the linker
options (as pointed out in the platform notes).
Or actually it's a bug in the whole way Windows handles shared libraries
in the first place (why again do we need __declspec(dllexport)?!). It
makes it impossible to write and use C++ libraries without ending up
with trouble one way or the other.

--
 [ signature omitted ]