Re: , definition of "used" for templates
On 6 Okt., 13:06, Jiang <goo.mai...@yahoo.com> wrote:
On Oct 5, 5:57 pm, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
Does the following program "use" the function "f"?
Your program uses function f's declaration, but not its
definition.
void f();
template<typename T>
void g() {
f();
}
int main() { }
3.2[basic.def.ord]p2:
"An expression is potentially evaluated unless it is an unevaluated operand
(Clause 5) or a subexpression thereof. A variable or non-overloaded function
whose name appears as a potentially-evaluated expression is used unless it
is an object that satis???es the requirements for appearing in a constant
expression (5.19) and the lvalue-to-rvalue conversion (4.1) is immediately
applied."
Is the above supplied program ill-formed because a definition of "f" is
missing ([basic.def.odr]p3)? If the program is valid, is there wording that
supports it?
The program is well-formed, since in 14.7.1 we have:
"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."
What you are referring to is a statement that applies to function
templates, but it does not apply to a non-template function.
The wording is not specified in a form that enforces a
compiler to realize a dependency analysis before assuming
that it can build-up references to entities.
For the same reason the following program is ill-formed:
extern int x;
template<typename T>
void g() {
int v = x;
}
int main() { }
This program requires the definition of x, even though g() is
not instantiated. The requirements for this are satisfied:
a) x occurs in a context that does belong to a potentially-
evaluated expression.
b) Within this context x appears in an expression where
it does not satisfy the criteria for a constant expression.
<insertion>
IMO the current wording regarding this point should be
reworded: 'x' is a reference-constant expression according
to C++03, but the current definition of 3.2/2 does not make
the difference clear. This becomes obvious if we would
have specified the following program:
extern int x;
template<int&> struct iref_t {};
template<typename T>
void g() {
iref_t<x> t;
constexpr auto px = &x;
}
int main() { }
In this variation x is not odr-used.
</insertion>
This on-demand instantiation feature shows the following
program is also valid.
template<typename T> void h();
int main() {}
* However, for ODR, obviously the word "uses" is limited to
definition, so in this context usually we say the program
does not use function f.
This is an invalid conclusion from the standard in regard to
the question, whether f() is odr-used in the example from the
OP or not. In your transformed program f() is indeed not used,
because it is not referenced at all.
Your assumption is that a compiler is required to perform
a dependency analysis before categorizing a function or
variable as unused - this is not the case! The binding of the
name f within g does not require two-phase name lookup
and an implementation may simply build-up extern
references for f when parsing template g().
HTH & Greetings from Bremen,
Daniel Kr??gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]