c++/736: Premature template method instantiation during specialization

m@loa.com m@loa.com
Sun Nov 5 09:46:00 GMT 2000


>Number:         736
>Category:       c++
>Synopsis:       Premature template method instantiation during specialization
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          rejects-legal
>Submitter-Id:   net
>Arrival-Date:   Sun Nov 05 09:46:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Nick Monyatovsky
>Release:        gcc version 2.95.2 19991024 (release)
>Organization:
>Environment:
RedHat Linux 6.2 on Intel x86
>Description:
The file attached demostrates a case where one template
method gets prematurely(?) instanted during a specialization of
another method.

Say, a() calls b().
We specialize a(): b() gets instantiated as a side-effect.

No other compilers tested have this symptom (SGI, HP aCC, SUN, IBM xlC,
COMPAQ cxx, MS VC++). They place a call to b() into a() as you
would expect, but do not write out the b()'s body as yet.

>How-To-Repeat:
>Fix:
There is a workaround: pre-declare A::second(), but it
is illegal to *declare* a template method outside the template
class definition(1), creates a different set of problems(2),
and makes it hard to port from other platforms to GNU(3).
>Release-Note:
>Audit-Trail:
>Unformatted:
 >>> g++ demo.C
 
 demo.C:39: specialization of A<char>::second() after instantiation
 demo.C:39: explicit specialization of A<char>::second() after first use
----gnatsweb-attachment----
Content-Type: text/plain; name="demo.C.txt"
Content-Disposition: inline; filename="demo.C.txt"

// This file demostrates a case where one template method gets prematurely(?)
// instantiated during a specialization of another method.
// A::first() has a specialization for "char". When the body of it gets
// instantiated, the method A::second() gets instantiated as well. 
// Problem 1: the 'generic' template implementation gets picked for second(),
//            not the specialized one (for "char").
// Problem 2: attempts to provide a specialization of second() for "char"
//            are rejected.
//
// No other compilers tested have this symptom (SGI, HP aCC, SUN, IBM xlC,
// COMPAQ cxx, MS VC++)
//
// TO REPRODUCE:
// 
// >>> g++ demo.C
//
// demo.C:39: specialization of A<char>::second() after instantiation
// demo.C:39: explicit specialization of A<char>::second() after first use


#include <iostream.h>

template<class T>
class A {
public:
  void first();
  void second();
};


template <>
void A<char>::first() 
{
   second(); // <--- Instantiation occurs here and *generic* definition is used.
}

template <>
void A<char>::second() // <-- This is considered an error as second() has already been instantiated
{
  cout << "Running second() specialized for char" << endl;
}


template<class T>
void A<T>::first() 
{
  second(); //<-- no definition has been seen yet. GNU will stumble.
}

template<class T>
void A<T>::second() 
{  
  cout << "Running generic second()" << endl;
}


template class A<int>;


int main() {
  A<int>  ai;
  A<char> ac;

  ai.first(); // int  - generic second() expected
  ac.first(); // char - specialized second() expected

  return 0;
}



More information about the Gcc-bugs mailing list