Incomplete type in nested name specifier

Introduction

There are several places in the standard that implicitly implies that your code is ill-formed, but the below quotation speaks for itself:

3.3.2p6 Point of declaration [basic.scope.pdecl]

After the point of declaration of a class member, the member name can be looked up in the scope of its class.

The problem with your code isn't that you try to reach inside the body of an incomplete type, the problem is that you can only refer to a class member name after it has been declared.

Since your forward-declaration (of course) doesn't introduce any member named c, it is ill-formed to refer to such name.


The misleading diagnostic...

The diagnostic issued by both gcc and clang when being fed your code is somewhat misleading, and honestly I feel a bug report is in order.

foo.cpp:3:8: error: incomplete type 'A' named in nested name specifier

We are allowed to name an incomplete type in a nested-name-specifier, but as said; we are not allowed to refer to a member that has not yet been declared.

ill-formed:

class X {
  static int a[X::x];        // ill-formed, `X::x` has not yet been declared
  static int const x = 123;
};

legal:

class X {
  int const x = 123;
  int a[X::x]; // legal, `X` is incomplete (since we are still defining it)
               //        but we can still refer to a _declared_ member of it
};