http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50479
Bug #: 50479 Summary: Unevaluated usage of parameters in function default arguments is accepted Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: daniel.krueg...@googlemail.com CC: ja...@redhat.com gcc 4.7.0 20110917 (experimental) accepts the following program with or without -Wall, -pedantic, or -std=c++0x: //--- long foo; void bar(char foo = sizeof(foo)) {} int main() { bar(); } //--- But according to 3.4.1 p11: "During the lookup for a name used as a default argument (8.3.6) in a function parameter-declaration-clause or used in the expression of a mem-initializer for a constructor (12.6.2), the function parameter names are visible and hide the names of entities declared in the block, class or namespace scopes containing the function declaration." and to 8.3.6 p9: "Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated. Parameters of a function declared before a default argument are in scope and can hide namespace and class member names." [The references refer to N3190, but also apply to C++03, 14882:2003(E)] the name 'foo' in the expression 'sizeof(foo)' should resolve to the parameter name and after this should make the program ill-formed. Refining this program to //--- extern "C" int printf(const char*, ...); long foo; void bar(char foo = sizeof(foo)) { int v = foo; printf("%d", v); } int main() { bar(); } //--- produces the output 4 leading to the conclusion that the name 'foo' is resolved to the name of the global variable, not to the parameter name. A similar example can be constructed via decltype and compiled successfully with -std=c++0x: //--- template<class> struct A; template<> struct A<long> { static const int value = 1; }; long foo; void bar(char foo = A<decltype(foo)>::value) {} int main() { bar(); } //--- This example should also be rejected for similar reasons as above, because the name 'foo' in the default argument should resolve to the parameter, but again the global variable name is found instead.