Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
324 views
in Technique[技术] by (71.8m points)

c++ - Interaction between decltype and class member name shadowing an external name

This code

int clash;

struct Foo {
  decltype(clash) clash;
};

compiles silently on clang, but fails to compile on gcc giving the errors

error: declaration of 'int Foo::clash' [-fpermissive]

error: changes meaning of 'clash' from 'int clash' [-fpermissive]

It seems that 2 ingredients are required for the error to arise:

  1. The shadowing must be done by a class member (no problem if it's a function's local scope).

  2. decltype([shadowed name]) must be used in the shadowing scope before the declaration of [shadowing name].

My question is twofold:

  1. Is gcc justified in rejecting this code?
  2. Where does it say so in the standard?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

gcc is correct the program is ill-formed, although this particular violation does not require a diagnostic so clang does not have to provide one.

If we look at the C++11 standard(The closest draft would be N3337) section 3.3.7 Class scope it 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.

and the next rule 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.

It makes sense we would want to prevent situations where reordering the declarations in a class give a different program. It is curious whether these two rules are redundant or not.

The section also provides 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 };
};

and if we try this example with gcc (see it live), we get an almost identical error to one your code produces:

 error: declaration of 'i' [-fpermissive]
 enum { i = 2 };
          ^

 error: changes meaning of 'i' from '<anonymous enum> i' [-fpermissive]
 enum { i = 1 };

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...