Re: C1001 ICE with .NET 2003 compiling templates

From: Andy Coates (nothanks_at_nowhere.com)
Date: 03/23/04


Date: Tue, 23 Mar 2004 18:00:59 -0000


"tom_usenet" <tom_usenet@hotmail.com> wrote in message
news:0vs060p2ctfao3e899883u2rsm2d6guk62@4ax.com...
> On 23 Mar 2004 07:52:42 -0800, programmer_blabla@hotmail.com
> (Programmer_blabla) wrote:
>
> >Dear all,
> >
> >I have spent the whole day figuring out a weird error. In the end I
> >could strip it down the following code snippet:
> >
> >template <typename T>
> >struct NCTestPointerTraits
> >{
> >};
> >
> >
> >template <typename T>
> >struct NCTestPointerTraits<T*>
> >{
> > enum {eSize = sizeof(T)};
>
> Note you can only use sizeof with complete types.
>
> >};
> >
> >
> >//leave other specializations...
> >
> >
> >template <typename T>
> >bool TestIsValidPointerExT(T* p, size_t nLen =
> >NCTestPointerTraits<T*>::eSize)
> >{
> > //return NCDbgMemory::IsValidPointerEx(p, nLen);
> > return true;
> >}
> >
> >
> >struct NCTestEmpty
> >{
> > NCTestEmpty()
> > : m_p(NULL)
> > {
> > }
> >
> > ~NCTestEmpty()
> > {
>
> (Workaround - add here:
> sizeof std::set<int>();)
>
> > TestIsValidPointerExT(m_p); //<-- GIVES ICE
>
> There seems to be a problem with VC7.1's implicit instantiation.
> std::set<int> should be instantiated by the sizeof in
> NCTestPointerTraits, but it isn't for some reason, and the compiler is
> going mad.
>
> >Using a map instead of set, one gets weird compiler errors. The set
> >gives an ICE, but the member m_p1(no STL or template) is accepted. Is
> >this legal C++, or is the compiler confused? Be aware that the pointer
> >must be declared as a member, just an ordinary local variable is
> >accepted.
>
> The workaround above gets rid of the error, but it is a bug of course
> - the code is legal (once you add the necessary #includes).
>
> Tom
> --
> C++ FAQ: http://www.parashift.com/c++-faq-lite/
> C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

My mistake - mistook what blabla was trying to do.

An alternative work around would be to move the nLen parameter of
TestIsValidPointerExT inside the function, so it becomes:

template <typename T>
bool TestIsValidPointerExT(T p)
{
 size_t nLen = NCTestPointerTraits<T>::eSize;
 return NCDbgMemory::IsValidPointerEx(p, nLen);
}

Then if you need another version that takes an aditional alternative len you
can just overload the function.

Andy