The declaration form proj (space(V[i]), V_new_i, "mass"); of an object 'proj' of class 'form' is not recognized, see below #include <vector> using std::vector; #include <string> struct space_component; struct const_space_component; template <class T> class smart_pointer { public: // allocators: smart_pointer (T* p = 0); smart_pointer (const smart_pointer&); ~smart_pointer (); smart_pointer& operator= (const smart_pointer&); // accessors: const T* pointer () const; const T& data () const; const T* operator-> () const; const T& operator* () const; // modifiers: T* pointer (); T* operator-> (); T& data (); T& operator* (); // implementation: }; typedef int basis; class spacerep { public: typedef std::vector<basis>::size_type size_type; spacerep(); }; class space : public smart_pointer<spacerep> { public: // typdefs: typedef spacerep::size_type size_type; // allocator/deallocator: space (); space(const const_space_component&); space_component operator [] (size_type i_comp); const_space_component operator [] (size_type i_comp) const; }; struct space_component { typedef space::size_type size_type; space_component(); space_component(space& V, size_type i); }; struct const_space_component { typedef space::size_type size_type; const_space_component(); const_space_component(const space_component&); }; class form { public : form (); form (const space& X, const space& Y, const std::string& op_name, bool locked_boundaries=false); }; int main() { space V, V_new_i; int i=1; form proj (space(V[i]), V_new_i, "mass"); /* error: parameter may not have variably modified type 'space [(((long unsigned int)(((long int)i) + -0x00000000000000001)) + 1)]' */ }
I don't think this is misparsing this at all. This is one place in the C++ standard that says it should be parsed as a function declaration rather than a variable declaration to resolve an ambiguous between those two.
(In reply to comment #1) > I don't think this is misparsing this at all. This is one place in the C++ > standard that says it should be parsed as a function declaration rather than a > variable declaration to resolve an ambiguous between those two. > There are different opinions about that. The current Comeau compiler does accept the code. Here an answer James Kanze on the news group comp.lang.c++ First, there is absolutely no way that proj can be interpreted as a function declaration; the string literal prevents that, regardless of anything else. Second, if "space" is the name of a type (as it is in your code), »space(V[i])« is a function declaration in any context that allows function declarations. The only contexts which allow declarations other than at the statement level, however, is as part of other declarations; the only context in which a function declaration can be followed by a comma is as a parameter in another function declaration. Since in this case, the string literal means that this statement cannot be a function declaration, »space(V[i])« cannot be a parameter declaration, and thus, cannot be a function declaration. There's no ambiguity. (This is a difficult parse, however, since the interpretation here depends on context. In something like: form proj( space(V[i]) ); »space(V[i])« is a function declaration, and the entire statement is a function declaration, because there is nothing which makes it illegal as a function declaration.) I do remember earlier versions of g++ (2.95.2?) having problems with this; they didn't consider context to the right of the expression when making the decision, so something like: form proj( space(V[i]), "abc" ); would fail to compile, treating »space(V[i])« as a function declaration, whereas: form proj( "abc", space(V[i]) ); worked, since the preceding string literal had removed the ambiguity of the context. Later versions of g++ fixed this. It sounds to me like they've reintroduced the bug, and that someone has decided (on what grounds, I don't know), that it's not a bug, but a feature. This is probably a shorter test case: struct A { A(int, char const*); }; int main() { int i = 0, *b = &i; A a(int(b[i]), "hello"); }
I agree with James Kanze's analysis.
Subject: Bug 41786 Author: jason Date: Tue Mar 30 21:19:23 2010 New Revision: 157838 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=157838 Log: PR c++/41185 PR c++/41786 * parser.c (cp_parser_direct_declarator): Don't allow VLAs in function parameter context. Don't print an error if parsing tentatively. Added: trunk/gcc/testsuite/g++.dg/parse/ambig5.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/parse/varmod1.C
Subject: Bug 41786 Author: jason Date: Tue Mar 30 21:20:58 2010 New Revision: 157839 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=157839 Log: PR c++/41185 PR c++/41786 * parser.c (cp_parser_direct_declarator): Don't allow VLAs in function parameter context. Don't print an error if parsing tentatively. Added: branches/gcc-4_4-branch/gcc/testsuite/g++.dg/parse/ambig5.C Modified: branches/gcc-4_4-branch/gcc/cp/ChangeLog branches/gcc-4_4-branch/gcc/cp/parser.c branches/gcc-4_4-branch/gcc/testsuite/ChangeLog branches/gcc-4_4-branch/gcc/testsuite/g++.dg/parse/varmod1.C
Fixed for 4.4.4 and 4.5.0.