From: Joshua Lehrer on 16 Jul 2010 01:20 I contend that the following code should not compile. However, on various compilers with varying versions of the EDG front end, it either crashes the compiler, compiles. or fails to compile. Am I correct that this code is ill-formed? template <typename F> inline void call(F func) { func(); } void routine(int i=3); int main() { call(&routine); } void routine(int i) { } -J -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 16 Jul 2010 07:38 On 16 Jul., 18:20, Joshua Lehrer <usenet_...(a)lehrerfamily.com> wrote: > I contend that the following code should not compile. However, on > various compilers with varying versions of the EDG front end, it > either crashes the compiler, compiles. or fails to compile. > > Am I correct that this code is ill-formed? > > template <typename F> > inline void call(F func) { func(); } > > void routine(int i=3); > > int main() { > call(&routine); > > } > > void routine(int i) { } The code is ill-formed, because function default arguments apply only to the concretely named function, not to a pointer to a function. Even, if the explicit address operator is removed, the compiler will deduce template paramteer F to void(*)(int) which means that a function call expression via this pointer must get an argument convertible to int. According to 8.3.5/4 in the C++03 standard: "[..] The return type, the parameter type list and the cv- qualifier-seq, but not the default arguments (8.3.6) or the exception specification (15.4), are part of the function type. [Note: function types are checked during the assignments and initializations of pointer-to-functions, reference-to- functions, and pointer-to-member-functions. ] [..]" 8.3.6/9 emphasizes this by normative wording: "[..] A default argument is not part of the type of a function. [Example: int f(int = 0); void h() { int j = f(1); int k = f(); // OK, means f(0) } int (*p1)(int) = &f; int (*p2)() = &f; // error: type mismatch [..]" 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! ]
From: Magnus Müller on 16 Jul 2010 07:37 On Fri, 16 Jul 2010 10:20:01 CST Joshua Lehrer <usenet_cpp(a)lehrerfamily.com> wrote: ::I contend that the following code should not compile. However, on ::various compilers with varying versions of the EDG front end, it ::either crashes the compiler, compiles. or fails to compile. :: ::Am I correct that this code is ill-formed? :: ::template <typename F> ::inline void call(F func) { func(); } :: ::void routine(int i=3); :: ::int main() { :: call(&routine); ::} :: ::void routine(int i) { } Based on my understanding, I consider this code illformed, as the signature of the function routine is void (*) (int). For the upper code to work, func should be deducted to void (*) (). Therefore, the call func () can't work. g++ behaves in this way: % make illformed g++ illformed.cc -o illformed illformed.cc: In function 'void call(F) [with F = void (*)(int)]': illformed.cc:10: instantiated from here illformed.cc:4: error: too few arguments to function So, g++ thinks this function is meant to have a parameter and doesn't care about the default argument. I guess other compilers should handle this issue in the same way. Regards, mm -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: Template instantiation question Next: anonymous namespace and C linkage |