1

The program

#include <iostream>

typedef int T;

struct A
{
    typedef char T;
    T i;
};

int main(){ }

should have been ill-formed, because N4296::3.3.7/5 [basic.scope.class]:

If reordering member declarations in a class yields an alternate valid program under (1) and (2), the program is ill-formed, no diagnostic is required.

But both clang and g++ compile it well

G++

CLANG

Is it their bug?

  • 6
    "no diagnostic is required". "no diagnostic is required". "no diagnostic is required". – T.C. Jan 28 '15 at 05:29

1 Answers1

0

If reordering member declarations in a class yields an alternate valid program under (1) and (2), the program is ill-formed, no diagnostic is required.

Despite the removal of this exact (superfluous) bullet point due to CWG issue #1875, note the bolded part; If we reorder the declarations

struct A
{
    T i;
    typedef char T;
};

The program is not conforming to rule 2):

2) A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

T is used in the declaration of i, where it refers to the global typedef. However, when reevaluated in the completed scope of A, T refers to the member typedef, which is clearly a different declaration.
This rule is not violated by your code, though.

The standard gives an example to show the difference between my first snippet and yours, and their validity. [basic.scope.class]/5:

typedef char* T;
struct Y {
    T a;             // error: T refers to ::T
                     // but when reevaluated is Y::T
    typedef long T;
    T b;
};

Thus the code in your question is indeed well-formed.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • This answer is not correct. Both codes are ill-formed (no diagnostic is required) – Belloc Jul 01 '15 at 14:35
  • @Belloc I cannot see why. The name `T` used does refer to the same name in both named evaluations of bullet point 2. Also consider the example added. – Columbo Jul 01 '15 at 16:01
  • @Columbo You're right. But the reason why the OP's code is not in error is because what used to be item (3) in [basic.scope.class]/1 was eliminated from the standard. I've just realized this change in N4527. – Belloc Jul 01 '15 at 21:07
  • @Belloc .. That bullet item was *superfluous*. Have you read my answer? – Columbo Jul 01 '15 at 21:44