[Bug c++/13503] New: name of type as constructor with operator [] or array subscripted operand is interpreted as name of type as declaration operator with [] as array subscript

bracz+gbz85 at math dot bme dot hu gcc-bugzilla@gcc.gnu.org
Mon Dec 29 15:32:00 GMT 2003


SHORTEST CODE TO TRIGGER:

class myclass {
};

class otherclass {
public:
  void dosomething() {}
  otherclass(myclass & c) {}
  otherclass() {}
};

int main() {
  myclass obj[2];
  otherclass(obj[1]).dosomething();  //<-- LOOK HERE
  return 0;
}

compiler fails with:
cpptest3.cpp:13: error: conflicting types for `otherclass obj[1]'
cpptest3.cpp:12: error: previous declaration as `myclass obj[2]'
cpptest3.cpp:13: error: syntax error before `.' token

EXPLANATION:
this means that g++ tries to declare a new variable 
otherclass (obj[1]);
(and of course it is illegal to append method calls to that, that is the syntax
error for).

ACTUAL USE:
The variable obj is not necessarily an array, it may be a class with operator[]
overloaded. Such as vector<T>.

shortest code:
#include <vector>
using  std::vector;
int main() {
  vector< vector<int> >obj;
  vector<int>a;    //this and the following line is irrelevant, 
  obj.push_back(a);//only to ensure that obj has at least one element
  vector<int>(obj[0]).swap(obj[0]); //<-- SWAP TRICK
  return 0;
}

The swap trick is for truncating a vector's capacity to its size. (It constructs
a temporary vector with the copy of the original vector's data, and the capacity
of its size, then swaps the containers, and finally it destructs the temporary
vector freeing the memory of the original.)
It is described in Scott Meyer's book `Effective STL programming'. This is a
special case where you try to truncate a row of a two-dimensional array.
We contacted him and he reported this code fragment to compile on all his
compilers except g++.


WORKAROUNDS:
Put the relevant line in a syntactic context where variable declaration is
illegal, like in an expression:

  (otherclass(obj[1]).dosomething());

or

  (otherclass(obj[1])).dosomething();


Or alternatively in the second case, one may use explicit operator[] call:
  vector<int>(obj.operator[](0)).swap(obj[0]);


NOTE 1:
This may be an issue of the c++ standard; I don't have the standard so I haven't
looked into it.

NOTE 2:
without the array subscript in the operand the parser does not get misleaded,
e.g. the following works fine:
vector<int> a;
vector<int>(a).swap(a);

this suggests that it is not the standard's issue.

-- 
           Summary: name of type as constructor with operator [] or array
                    subscripted operand is interpreted as name of type as
                    declaration operator with [] as array subscript
           Product: gcc
           Version: 3.3.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: bracz+gbz85 at math dot bme dot hu
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13503



More information about the Gcc-bugs mailing list