Signalling errors in function template code: instantiation dependent?
In some instances, in relation to code contained in the body of a
function template, it appears that implementations are granted choices
about exactly when and under what conditions errors are signalled. For
instance, with regard to point-of-definition errors, MSVC apparently
only signals such errors upon instantiation of a function template,
whereas GCC takes the opportunity to signal these without requiring
instantiation. (I believe, although I'd be happy to have it clarified,
that both strategies are equally valid in such instances.)
What has surprised me recently, however, is that I have stumbled upon an
instance where GCC seems to straddle these strategies in relation to
what, on the face of it, appear to be errors meriting similar treatment.
Given the following code, taken directly from [temp.param]/6 and
complete with the comments given there (plus forward declaration of
class X and empty main)...:
/cygdrive/d/CPPProjects/nano $cat temp_param_6.cpp
// file: temp_param_6.cpp
class X;
template<const X& x, int i> void f()
{
i++; // error: change of template-parameter value
&x; // OK
&i; // error: address of non-reference template
// parameter
int& ri = i; // error: non-const reference bound to
// temporary const int& cri = i; // OK: const reference bound to temporary
}
int main() { }
....we see that there are three errors here. Compiling with gcc-4.4.3,
the first error alone is picked up in a context without instantiation, so:
17:38:51 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/nano $gcc -c temp_param_6.cpp
temp_param_6.cpp: In function ??void f()??:
temp_param_6.cpp:7: error: increment of read-only location ??i??
Then, it is only through effecting an instantiation...:
int main()
{
extern const X x;
f<x, 42>();
}
....that GCC picks up the other two:
17:42:48 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/nano $gcc -c temp_param_6.cpp
temp_param_6.cpp: In function ??void f()??:
temp_param_6.cpp:7: error: increment of read-only location ??i??
temp_param_6.cpp: In function ??void f() [with const X& x = ((const
X&)(& x)), int i = 42]??: temp_param_6.cpp:20: instantiated from here
temp_param_6.cpp:7: error: lvalue required as increment operand
temp_param_6.cpp:10: error: lvalue required as unary ??&?? operand
temp_param_6.cpp:12: error: invalid initialization of non-const
reference of type ??int&?? from a temporary of type ??int??
Yet, unless there are some subtleties at play here that I have missed, I
can't immediately see why the first does not require instantiation to
be an error whilst the second and third do.
Clarification welcomed!
Regards
Paul Bibbings
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]