Re: Bug or feature? C++ code that no longer compiles under GCC 4.2
On Thu, 2007-08-30 at 10:05 +1000, Jonathan Adamczewski wrote: I don't have gcc-4.2 handy - does changing this to a const reference solve the problem? i.e templatetypename Op void foo(const Op op) { op(); } Thanks for the suggestion, it doesn't help: test.cpp: In member function 'void My::test()': test.cpp:12: error: invalid initialization of non-const reference of type 'void ()()' from a temporary of type 'void ()()' test.cpp:4: error: in passing argument 1 of 'void foo(const Op) [with Op = void ()()]' -- Daniel Drake Brontes Technologies, A 3M Company http://www.brontes3d.com/opensource
Re: Bug or feature? C++ code that no longer compiles under GCC 4.2
On ons, 2007-08-29 at 16:42 -0400, Daniel Drake wrote: Hi, Take the following code sample: #define BREAK_GCC4_2 templatetypename Op void foo(Op op) { op(); } class My { public: static void myOp() { } void test() { #ifdef BREAK_GCC4_2 foo(myOp); #else foo(My::myOp); #endif } }; It compiled fine under GCC 4.1 but fails under 4.2.0: $ g++ -c test.cpp test.cpp: In member function 'void My::test()': test.cpp:12: error: invalid initialization of non-const reference of type 'void ()()' from a temporary of type 'void ()()' test.cpp:4: error: in passing argument 1 of 'void foo(Op) [with Op = void ()()]' We found an alternative way to make the code compile (comment out the first line) which works with both versions, but I'm wondering whether this should be reported as a bug or if it was intentional. I think this is a feature, and your old code were buggy. ISO 14882:1998 states (§5.3.1p3) A pointer to member is only formed when an explicit is used and its operand is a qualified-id not enclosed in parentheses. and then goes on to say (in a note, so this isn't normative) Nor is unqualified-id a pointer to member, even within the scope of the unqualified-id's class. /MF
Re: Bug or feature? C++ code that no longer compiles under GCC 4.2
On ons, 2007-08-29 at 16:42 -0400, Daniel Drake wrote: #define BREAK_GCC4_2 templatetypename Op void foo(Op op) { op(); } class My { public: static void myOp() { } void test() { #ifdef BREAK_GCC4_2 foo(myOp); #else foo(My::myOp); #endif } }; On Thu, Aug 30, 2007 at 10:51:03PM +0200, Magnus Fromreide wrote: I think this is a feature, and your old code were buggy. ISO 14882:1998 states (§5.3.1p3) A pointer to member is only formed when an explicit is used and its operand is a qualified-id not enclosed in parentheses. But taking the address of myOp does not produce a pointer-to-member, as it is a static function; My::myOp is a pointer to an ordinary function. Just the same, you need the to make an ordinary pointer-to-function as well. Then the other problem is the attempt to bind a non-lvalue to a non-const reference. If I fix both of those problems, I get templatetypename Op void foo(const Op op) { op();} class My { public: static void myOp() {} void test() { foo(myOp); } }; and 4.2.1 accepts it. However, if I omit the ampersand and write templatetypename Op void foo(const Op op) { op();} // line 2 class My { public: static void myOp() {} void test() { foo(myOp); // line 8 } }; I get foop_noamp.cpp: In member function 'void My::test()': foop_noamp.cpp:8: error: invalid initialization of non-const reference of type 'void ()()' from a temporary of type 'void ()()' foop_noamp.cpp:2: error: in passing argument 1 of 'void foo(const Op) [with Op = void ()()]' The error message here is bogus; there is no non-const reference. So for users, the message is to use an ampersand to form the pointer-to-function or pointer-to-member, and to use a const reference if you aren't passing an lvalue.
Bug or feature? C++ code that no longer compiles under GCC 4.2
Hi, Take the following code sample: #define BREAK_GCC4_2 templatetypename Op void foo(Op op) { op(); } class My { public: static void myOp() { } void test() { #ifdef BREAK_GCC4_2 foo(myOp); #else foo(My::myOp); #endif } }; It compiled fine under GCC 4.1 but fails under 4.2.0: $ g++ -c test.cpp test.cpp: In member function 'void My::test()': test.cpp:12: error: invalid initialization of non-const reference of type 'void ()()' from a temporary of type 'void ()()' test.cpp:4: error: in passing argument 1 of 'void foo(Op) [with Op = void ()()]' We found an alternative way to make the code compile (comment out the first line) which works with both versions, but I'm wondering whether this should be reported as a bug or if it was intentional. Thanks! -- Daniel Drake Brontes Technologies, A 3M Company http://www.brontes3d.com/opensource