I recently answered a question dealing with a violation of draft C++14 standard: N4140 section 3.3.7
Class scope paragraph 1
rule 2
which says:
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.
at the time rule 3
also seemed relevant and it says:
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.
My initial reaction is that rule 3
seems redundant and is really just a clarification of rule 2
and does not cover any cases not already covered. A reordering that results in a alternate valid program would also have to violate rule 2
.
So is rule 3
redundant or is there some edge cases that requires both rules?
According to Defect Report 1875: Reordering declarations in class scope rule 3
is redundant and the proposed solution is to remove rule 3
, it says:
The need for rule #3 is not clear; it would seem that any
otherwise-valid reordering would have to violate rule #2 in order to
yield a different interpretation. Taken literally, rule #3 would also
apply to simply reordering nonstatic data members with no name
dependencies at all. Can it be simply removed?
and the proposed solution is:
Delete the third item of 3.3.7 [basic.scope.class] paragraph 1 and
renumber the succeeding items
Although this defect report seems to confirm my initial suspicious I am left with a nagging feeling that perhaps rule 3
is bit broader after all. Section 3.3.7
includes the following example:
enum { i = 1 };
class X {
char v[i]; // error: i refers to ::i
// but when reevaluated is X::i
int f() { return sizeof(c); } // OK: X::c
char c;
enum { i = 2 };
};
which violates both rule 2
and 3
but a small tweak:
enum { i = 1 };
class X {
enum { i = 2 };
char v[i]; // no longer refers to ::i
// but reordering can cause it to refer to ::i again
int f() { return sizeof(c); } // OK: X::c
char c;
};
seems to no longer violate rule 2
but sure seems to violate rule 3
. I would consider this code example to be troublesome since a reordering of the members could easily cause the code to be back in violation of rule 2 but no diagnostic is required to indicate this which makes this code rather fragile.
Update
As far as I understand rule 3
does not apply to this example mentioned by Casey in the comment:
class X { int a; int b; };
because even though there is more than one valid ordering this case does not fall under both rule 1
and 2
which rule 3
requires:
alternate valid program under (1) and (2)