C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Legality of class template member functions without a defini

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Craig Scott
Guest





PostPosted: Tue Dec 05, 2006 10:10 am    Post subject: Legality of class template member functions without a defini Reply with quote



After repeatedly trying to get a definitive answer from the c++
standard, I would like to ask for opinions on whether people consider
the following code to be standard conforming:

// fileA.h:
template<typename T> struct Foo {
// This function is defined and explicitly instantiated in
// a different compilation unit
static T func();
};

// fileA.cpp
#include "fileA.h"
int main()
{
return Foo<int>::func(); // Function body not visible
}

// fileB.cpp:
#include "fileA.h"
template<typename T> T Foo<T>::func()
{
// This could be anything. This example just returns a
// default-constructed object.
return T();
}
template struct Foo<int>; // Explicitly instantiate for int

Note that the body of Foo<T>::func is not provided with the Foo class
template's definition. Instead, it is defined in a separate file which
also explicitly instantiates it for the type "int". With the above
code, is the call to Foo<int>::func() legal in File A? I have been
unable to get a definitive answer from my readings of the C++ standard.
I also note the following:

- The example appears to compile just fine (a weak test, but stated for
completeness)

- The C++ FAQ item 35.13 seems to imply that this is okay, but it is
the C++ standard that seems ambiguous to me and I need a definitive
answer.

- Vandevoorde and Josuttis appear to rely on this being valid in their
"C++ Templates" book (see section 10.5, although this was to do with
function templates rather than member functions of class templates).

- According to the C++ standard, if Foo<int>::func() was declared to be
explicitly specialized but still no definition is supplied before it
was called, this is okay as long as there exists somewhere in the
program an instantiation of that function (at least, that's my
understanding of the standard).

Anyone able to definitively say whether the above example is legal? The
above technique seems to be an accepted practice but the standard
doesn't seem so clear-cut to me.

--
Computational Fluid Dynamics, CSIRO (CMIS)
Melbourne, Australia


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Craig Scott
Guest





PostPosted: Fri Dec 08, 2006 10:10 am    Post subject: Re: Legality of class template member functions without a d Reply with quote



Quote:
// fileA.h:
template<typename T> struct Foo {
// This function is defined and explicitly instantiated in
// a different compilation unit
static T func();
};

// fileA.cpp
#include "fileA.h"
int main()
{
return Foo<int>::func(); // Function body not visible
}

// fileB.cpp:
#include "fileA.h"
template<typename T> T Foo<T>::func()
{
// This could be anything. This example just returns a
// default-constructed object.
return T();
}
template struct Foo<int>; // Explicitly instantiate for int

AFAIK, the code is illegal. fileA.cpp shall trigger an implicit
instantiation, according to 14.7.1/1. Notice that the clause "Unless a
member of a class template or a member template has been explicitly
instantiated or explicitly specialized, [...]" does not apply in this
case, because even if the template is indeed being explicitly
instantiated, the explicit instantiation is not visible in fileA.cpp.

It would seem that there is more weight to the argument that the code
is illegal. That said, is anyone aware of a compiler where the example
as originally posted (and quoted above) does NOT compile?

--
Computational Fluid Dynamics, CSIRO (CMIS)
Melbourne, Australia


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Greg Herlihy
Guest





PostPosted: Sat Dec 09, 2006 3:51 am    Post subject: Re: Legality of class template member functions without a de Reply with quote



Craig Scott wrote:
Quote:
§14.8.3/5-6 in the latest draft of the C++ Standard answers your
question:

"Only the signature of a function template specialization is needed to
enter the specialization in a set of candidate functions. Therefore
only the function template declaration is needed to resolve a call for
which a template specialization is a candidate."

The Standard then provides an example of function call to a
declared-but-not-yet-defined function template, f(), and concludes:

"The program will be ill-formed unless a specialization for f<const
char*>, either implicitly or explicitly generated, is present in some
translation unit. -- end example]"

Does the latest draft also make this clear for member functions of a
class template, or just for template (free) functions? It would seem
strange if it did not.

The phrase "function template" in C++ Standardese refers both to
templates (that are functions) and to functions that are generated by
(class) templates (see Core Language Issue #105). Certainly for the
purpose of overload resolution (which the quoted text was describing)
they are both treated indiscriminately as "function templates".

In any case, the latest draft of the C++ Standard also states:

"A non-exported non-class template must be defined in every translation
unit in which it is implicitly instantiated, unless the corresponding
specialization is explicitly instantiated in some translation unit; no
diagnostic is required." §14/9

If you want language any more clear, you will have to provide your own
wording. :-)

It's also possible to approach the question from the other end: how
could the above program not be legal? There is in fact no reasonable
basis for concluding that the program above is illegal. After all, if a
C++ program can call a non-template function without that function's
definition being visible at the point of the call, then why would a
call to a function template need the template function's definition to
be visible under otherwise identical circumstances? The answer of
course is that there would be no rational basis for the Standard to
make such a distinction - and that helps to explain (in some small
measure) why no such irrational requirement actually is present in the
C++ Standard.

Greg


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alberto Ganesh Barbati
Guest





PostPosted: Sat Dec 09, 2006 3:52 am    Post subject: Re: Legality of class template member functions without a de Reply with quote

Greg Herlihy ha scritto:
Quote:

§14.8.3/5-6 in the latest draft of the C++ Standard answers your
question:

"Only the signature of a function template specialization is needed to
enter the specialization in a set of candidate functions. Therefore
only the function template declaration is needed to resolve a call for
which a template specialization is a candidate."

Off the main topic, where the problem is about the multiple
instantiation of the class template, not its member function, this
clause bothers me. Compare that with §14.7.1/2: "Unless a function
template specialization has been explicitly instantiated or explicitly
specialized, the function template specialization is implicitly
instantiated when the specialization is referenced in a context that
requires a function definition to exist."

One interesting question is: what is a "context that requires a function
definition to exists"? §14.8.3/6 says that even resolving a call does
not require the definition, so I'm left wondering what is left that
could require it.

Consider this example, using function templates for simplicity:

--- fileA.h

template <class T> void foo(T x);

--- fileA.cpp

#include "fileA.h"

template <class T> void foo(T x) { }
template void foo(int x); // explicit instantiation

--- main.cpp

#include "fileA.h"

int main()
{
foo(0); // implicit instantiation?
}

Should main.cpp try to implicitly instantiate the template? According to
§14.8.3/5 it shouldn't (because the definition is not needed) and it's
not a big deal, because fileA.cpp is providing an explicit
instantiation. Moreover main.cpp could not instantiate the template
anyway, because no definition is visible at the point of call.

Now let's move the definition of the template out of fileA.cpp and into
fileA.h:


--- fileA.h

template <class T> void foo(T x) {}

--- fileA.cpp

#include "fileA.h"

template void foo(int x); // explicit instantiation

--- main.cpp

#include "fileA.h"

int main()
{
foo(0); // implicit instantiation?
}

Should main.cpp try to implicitly instantiate the template? If we apply
the argument above literally, the answer would be no, because the fact
that now a definition is visible in main.cpp doesn't make any difference
(please suspend judgment about this point until you have read everything
below, I know there's the contradiction here).

Now let's remove fileA.cpp from the program... we *know* that the
program is actually well-formed and that implicit instantiation will
happen, but... who is requesting it?

Then we reached a second interesting question: what is meant in
§14.7.1/2 with the words "Unless a function template specialization has
been explicitly instantiated or explicitly specialized"? In particular,
*where* the explicit instantiation or specialization should be found?
It's very ambiguous. It could be either:

"Unless an explicitly instantiation or explicitly specialization is
visible"

or

"Unless an explicitly instantiation or explicitly specialization is
available in the program, possibly provided by another translation unit"

Of course, the second one can't be accepted because it would require the
linker, which is the only one who can see all translation units at once,
to choose whether to perform the instantiation or not. So we are left
with the first one.

Summarizing, what is happening is that the visibility of the template
definition not only affects the triggering of the implicit
instantiation, but it appears to be both a necessary and a sufficient
condition for it, once the function has been selected among overload
candidates. Unless I'm very mistaken about this conclusion, I think the
standard should really clarify this issue.

Any comments?

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Greg Herlihy
Guest





PostPosted: Sat Dec 09, 2006 3:53 am    Post subject: Re: Legality of class template member functions without a de Reply with quote

Alberto Ganesh Barbati wrote:
Quote:
Craig Scott ha scritto:
After repeatedly trying to get a definitive answer from the c++
standard, I would like to ask for opinions on whether people consider
the following code to be standard conforming:

// fileA.h:
template<typename T> struct Foo {
// This function is defined and explicitly instantiated in
// a different compilation unit
static T func();
};

// fileA.cpp
#include "fileA.h"
int main()
{
return Foo<int>::func(); // Function body not visible
}

// fileB.cpp:
#include "fileA.h"
template<typename T> T Foo<T>::func()
{
// This could be anything. This example just returns a
// default-constructed object.
return T();
}
template struct Foo<int>; // Explicitly instantiate for int

AFAIK, the code is illegal. fileA.cpp shall trigger an implicit
instantiation, according to 14.7.1/1. Notice that the clause "Unless a
member of a class template or a member template has been explicitly
instantiated or explicitly specialized, [...]" does not apply in this
case, because even if the template is indeed being explicitly
instantiated, the explicit instantiation is not visible in fileA.cpp.

There is no wording in this section that requires that the explicit
template instantiation be visible - only that it exist. And since an
explicit instantiation for foo<int> does exist in the sample program,
the Standard's requirements are met.

Quote:
That said, the code is illegal because a template is being both
implicitly and explicitly instantiated (14.7/4).

§14.7/ 4 does not mention explicit instantiation - only explicit
specialization and implicit instantiation of a template.

Quote:
- Vandevoorde and Josuttis appear to rely on this being valid in their
"C++ Templates" book (see section 10.5, although this was to do with
function templates rather than member functions of class templates).

No, it's clearly said that it cannot be done "in a portable matter" and
that "at the time of writing (2002) the C++ standardization committee
appears inclined to [do something about it]". That "something" is what I
reported above, which is different from that two authors expected at
that time.

On the contrary, the Vandevoorde/Josuttis book states that:

"...the only portable way to ensure this inhibition [of a template
instantiation] is not to provide the template definition except in the
translation unit where it is explicitly instantiated."

and the program above conforms completely to that portable behavior.

Quote:
- According to the C++ standard, if Foo<int>::func() was declared to be
explicitly specialized but still no definition is supplied before it
was called, this is okay as long as there exists somewhere in the
program an instantiation of that function (at least, that's my
understanding of the standard).

It's apparent to me that implicit instantiation shall occur, but it's
not specified what shall happen if no definition is available. So we
can't actually say it's ok. Tertium non datur, it can't be ok. However,
I think this case should be clarified. For example it is said explicitly
for class templates 14.7.1/6, why not functions? Even the most recent
draft of C++0x does not provide more insight.

If it's OK for an ordinary function to be called without its definition
visible, what would be the reason for thinking that function templates
would have to be called any differently?

Greg


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.