Potential bug in typeof (gnu extension) parsing

I was mucking about with typeof (discovered it looking at DeclSpecs various SourceLocation information trying to piece together SourceLocations/Ranges covering the entire return type both before & after the identifier) & I discovered this curious behavior:

Given this:

int i = 3;
typeof(i) (*foo())() {

The following output is provided

  typeof.cpp:2:13: error: use of undeclared identifier 'foo'
  typeof(i) (*foo())()
  typeof.cc:4:2: error: expected unqualified-id

If I use a simple function (typeof(i) foo() {}) it compiles fine. If I use gcc/g++ I get a very similar error to the one clang provides. So it’s at least bug-for-bug compatible, but I’m wondering what the desired behavior is here & why this case would be failing in the way it is.

Interestingly, C++0x’s decltype works totally fine here (ie: compiles without error). So I’m wondering: in what way is typeof not just an alias for decltype? Should it be? (could we remove some redundant code in clang by coalescing these two cases together) Or is there some legitimate reason for these errors.

  • David

The grammar of typeof in C++ is "typeof unary-expression". Note the
lack of parentheses in this production. Granted, it isn't
particularly sane, which is why decltype is not defined that way.


Hmm, that is rather cunning (& not at all clear from the simple examples on the GNU documentation page for the feature http://gcc.gnu.org/onlinedocs/gcc/Typeof.html ). So it was parsing my expression as:

typeof ((y) (*x)())

basically. Which could be valid if y was something callable (with the result of unary* on x), that when called was itself callable (with no args). Yeah, that’s got to be rather annoying to parse/deal with.

Thanks Eli,

  • David

To supplement this, typeof is not an alias for decltype because it always
yields the type of the expression, whereas decltype will sometimes yield
a reference type, depending on the syntactic form of the operand.