N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(13) 3.3.7 Class scope [basic.scope.class]

はじめに

N4606 Working Draft, Standard for Programming Language C++
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/#mailing2016-11
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

n4606は、ISO/IEC JTC1 SC22 WG21の作業原案(Working Draft)です。
公式のISO/IEC 14882原本ではありません。
ISO/IEC JTC1 SC22 WG21では、可能な限り作業文書を公開し、幅広い意見を求めています。
一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(g++, Clang++)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
また、CERT C++, MISRA C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的な擦れの確認が結果としてできれば幸いです。

list

N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(1) coding list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/

Compiler

clang++ --version

clang version 6.0.0 (tags/RELEASE_600/final)

g++-7 --version

g++-7 (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.

(13)3.3.7 Class scope [basic.scope.class]

p.44

p44.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf 
#define msg "p44.cpp(13)3.3.7 Class scope [basic.scope.class]"

#include <iostream>

// from here p.44
typedef int c;
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 };
};
typedef char* T;
struct Y {
  T a; // error: T refers to ::T
  // but when reevaluated is Y::T
  typedef long T;
  T b;
};
typedef int I;
class D {
  typedef I I; // error, even though no reordering involved
};
// to here p45
int main(int argc, char *argv[], char *envp[]){

  std::cout << msg << std::endl;
  return EXIT_SUCCESS;
}
$ ./cppgl.sh p44
$ clang++ p44.cpp
p44.cpp(13)3.3.7 Class scope [basic.scope.class]

$ g++-7 p44.cpp
p44.cpp:15:14: error: declaration of 'i' [-fpermissive]
   enum { i = 2 };
              ^
p44.cpp:9:8: error: changes meaning of 'i' from '<unnamed enum> i' [-fpermissive]
 enum { i = 1 };
        ^
p44.cpp:21:16: error: declaration of 'typedef long int Y::T' [-fpermissive]
   typedef long T;
                ^
p44.cpp:17:15: error: changes meaning of 'T' from 'typedef char* T' [-fpermissive]
 typedef char* T;
               ^
p44.cpp:26:13: error: declaration of 'typedef I D::I' [-fpermissive]
   typedef I I; // error, even though no reordering involved
             ^
p44.cpp:24:13: error: changes meaning of 'I' from 'typedef int I' [-fpermissive]
 typedef int I;
             ^
p44a.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf 
#define msg "p44a.cpp (13)3.3.7 Class scope [basic.scope.class]"

#include <iostream>

// from here p.44
typedef int c;
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 };
//$ g++-7 p44.cpp
//p44.cpp:15:14: error: declaration of 'i' [-fpermissive]
//   enum { i = 2 };
//              ^
//p44.cpp:9:8: error: changes meaning of 'i' from '<unnamed enum> i' [-fpermissive]
// enum { i = 1 };
//        ^
};
typedef char* T;
struct Y {
  T a; // error: T refers to ::T
  // but when reevaluated is Y::T
//  typedef long T;
//$ g++-7 p44.cpp
//p44.cpp:21:16: error: declaration of 'typedef long int //Y::T' [-fpermissive]
//   typedef long T;
//                ^
//p44.cpp:17:15: error: changes meaning of 'T' from //'typedef char* T' [-fpermissive]
// typedef char* T;
//               ^
  T b;
};
typedef int I;
class D {
//  typedef I I; // error, even though no reordering involved
//$ g++-7 p44.cpp
//p44.cpp:26:13: error: declaration of 'typedef I D::I' [-fpermissive]
//   typedef I I; // error, even though no reordering involved
//             ^
//p44.cpp:24:13: error: changes meaning of 'I' from 'typedef int I' [-fpermissive]
// typedef int I;
//             ^
};
// to here p45
int main(int argc, char *argv[], char *envp[]){

  std::cout << msg << std::endl;
  return EXIT_SUCCESS;
}
$ ./cppgl.sh p44a
$ clang++ p44a.cpp
p44a.cpp (13)3.3.7 Class scope [basic.scope.class]

$ g++-7 p44a.cpp
p44a.cpp (13)3.3.7 Class scope [basic.scope.class]

課題

1)g++とclang++の違い

g++でエラーになった3項目がclang++ではエラーになっていない。

2) 規格の想定と処理系の違い(?)

char v[i]; // error: i refers to ::i
規格は呼び出し場所でのエラーを想定している。g++は宣言場所でのエラーを出力している。

参考資料

コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)
https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da
Qiitaに投稿するCのStyle例(暫定)
https://qiita.com/kaizen_nagoya/items/946df1528a6a1ef2bc0d

文書履歴

0.10 初稿 2080415

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.