LoginSignup
2
0

More than 1 year has passed since last update.

N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(53) 5.20 Constant expressions [expr.const] p138

Last updated at Posted at 2018-04-16

はじめに

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++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、Linux OS, TOPPERSカーネル、g++(GCC), clang++(LLVM)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。

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.

#(53)5.20 Constant expressions [expr.const]
p138

##p138 初稿

p138.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf 
#define msg "p138.cpp(53)5.20 Constant expressions [expr.const]"

#include <iostream>

void g() {
  const int n = 0;
  [=] {
  constexpr int i = n; // OK, n is not odr-used and not captured here
  constexpr int j = *&n; // ill-formed, &n would be an odr-use of n
  };
}

auto monad = { return [=] { return v; }; };
auto bind = {
  return = { return fvm(m()); };
};
// OK to have captures to automatic objects created during constant expression evaluation.
static_assert(bind(monad(2))(monad)() == monad(2)());
int x; // not constant
struct A {
  constexpr A(bool b) : m(b?42:x) { }
  int m;
};
constexpr int v = A(true).m; // OK: constructor call initializes
// m with the value 42
constexpr int w = A(false).m; // error: initializer for m is
// x, which is non-constant
constexpr int f1(int k) {
  constexpr int x = k; // error: x is not initialized by a
  // constant expression because lifetime of k
  // began outside the initializer of x
  return x;
}
constexpr int f2(int k) {
  int x = k; // OK: not required to be a constant expression
  // because x is not constexpr
  return x;
}
constexpr int incr(int &n) {
  return ++n;
}
constexpr int g(int k) {
  constexpr int x = incr(k); // error: incr(k) is not a core constant
  // expression because lifetime of k
  // began outside the expression incr(k)
  return x;
}
constexpr int h(int k) {
  int x = incr(k); // OK: incr(k) is not required to be a core
  // constant expression
  return x;
}
constexpr int y = h(1); // OK: initializes y with the value 2
// h(1) is a core constant expression because
// the lifetime of k begins inside h(1)
int main(){
 
  std::cout << "z="<<z<<" a="<<a<<" t="<<b<< " c="<<c<<"f(a, (t=3, t+2), c) ="<< f(a, (t=3, t+2), c);
  std::cout << std::endl<< msg << std::endl;
  return EXIT_SUCCESS;
}
$ ./cppgl17.sh p138
$ clang++ p138.cpp
p138.cpp:9:3: warning: expression result unused [-Wunused-value]
  [=] {
  ^~~~~
p138.cpp:15:16: error: expected expression
auto monad = { return [=] { return v; }; };
               ^
p138.cpp:17:3: error: expected expression
  return = { return fvm(m()); };
  ^
p138.cpp:28:15: error: constexpr variable 'w' must be initialized by a constant expression
constexpr int w = A(false).m; // error: initializer for m is
              ^   ~~~~~~~~~~
p138.cpp:23:32: note: read of non-const variable 'x' is not allowed in a constant expression
  constexpr A(bool b) : m(b?42:x) { }
                               ^
p138.cpp:28:19: note: in call to 'A(false)'
constexpr int w = A(false).m; // error: initializer for m is
                  ^
p138.cpp:21:5: note: declared here
int x; // not constant
    ^
p138.cpp:31:17: error: constexpr variable 'x' must be initialized by a constant expression
  constexpr int x = k; // error: x is not initialized by a
                ^   ~
p138.cpp:31:21: note: read of non-const variable 'k' is not allowed in a constant expression
  constexpr int x = k; // error: x is not initialized by a
                    ^
p138.cpp:30:22: note: declared here
constexpr int f1(int k) {
                     ^
p138.cpp:45:17: error: constexpr variable 'x' must be initialized by a constant expression
  constexpr int x = incr(k); // error: incr(k) is not a core constant
                ^   ~~~~~~~
p138.cpp:42:10: note: a constant expression cannot modify an object that is visible outside that expression
  return ++n;
         ^
p138.cpp:45:21: note: in call to 'incr(k)'
  constexpr int x = incr(k); // error: incr(k) is not a core constant
                    ^
1 warning and 5 errors generated.

$ g++-7 p138.cpp
p138.cpp: In lambda function:
p138.cpp:11:23: error: lvalue required as unary '&' operand
   constexpr int j = *&n; // ill-formed, &n would be an odr-use of n
                       ^
p138.cpp: At global scope:
p138.cpp:15:16: error: expected primary-expression before 'return'
 auto monad = { return [=] { return v; }; };
                ^~~~~~
p138.cpp:15:16: error: expected '}' before 'return'
p138.cpp:15:16: error: unable to deduce 'std::initializer_list<auto>' from '{<expression error>}'
p138.cpp:15:16: error: expected ',' or ';' before 'return'
p138.cpp:15:42: error: expected declaration before '}' token
 auto monad = { return [=] { return v; }; };
                                          ^

変数重複等により分割

p138-2.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf 
#define msg "p138-2.cpp(53)5.20 Constant expressions [expr.const]"

#include <iostream>

bool f() {
  char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation
  int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime
  return sizeof(array) == size;
}
struct A {
  constexpr A(int i) : val(i) { }
  constexpr operator int() const { return val; }
  constexpr operator long() const { return 43; }
  private:
  int val;
};

template<int> struct X { };
constexpr A a = 42;
X<a> x; // OK: unique conversion to int
int ary[a]; // error: ambiguous conversion

int main(){
  std::cout << std::endl<< msg << std::endl;
  return EXIT_SUCCESS;
}
$ ./cppgl17.sh p138-2
$ clang++ p138-2.cpp
p138-2.cpp:19:19: error: class cannot be defined in an explicit instantiation; if this declaration is meant to be a class definition, remove the
      'template' keyword
template struct X { };
~~~~~~~~~         ^
p138-2.cpp:22:9: error: size of array has non-integer type 'const A'
int ary[a]; // error: ambiguous conversion
        ^
2 errors generated.

$ g++-7 p138-2.cpp
p138-2.cpp:19:21: error: explicit instantiation of non-template type 'X'
 template struct X { };
                     ^
p138-2.cpp:22:10: error: ambiguous default type conversion from 'const A'
 int ary[a]; // error: ambiguous conversion
          ^
p138-2.cpp:22:10: note:   candidate conversions include 'constexpr A::operator int() const' and 'constexpr A::operator long int() const'

p138-2a.cpp @nishiyama_d さん

からの編集リクエストによる訂正後

p138-2a.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
#define msg "p138-2a.cpp(53)5.20 Constant expressions [expr.const]"

#include <iostream>

bool f() {
  char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation
  int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime
  return sizeof(array) == size;
}
struct A {
  constexpr A(int i) : val(i) { }
  constexpr operator int() const { return val; }
  constexpr operator long() const { return 43; }
  private:
  int val;
};
template<int> struct X { };
constexpr A a = 42;
X<a> x; // OK: unique conversion to int
int ary[a]; // error: ambiguous conversion

int main(){
  std::cout << std::endl<< msg << std::endl;
  return EXIT_SUCCESS;
}
$ ./cppgl17.sh p138-2a
$ clang++ p138-2a.cpp
p138-2a.cpp:22:9: error: size of array has non-integer type 'const A'
int ary[a]; // error: ambiguous conversion
        ^
1 error generated.

$ g++-7 p138-2a.cpp
p138-2a.cpp:22:10: error: ambiguous default type conversion from 'const A'
 int ary[a]; // error: ambiguous conversion
          ^
p138-2a.cpp:22:10: note:   candidate conversions include 'constexpr A::operator int() const' and 'constexpr A::operator long int() const'

#検討事項
コンパイルエラーの出ない修正。
意味のある出力

参考資料

コンパイル用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

MISRA C++ 5-0-16
https://qiita.com/kaizen_nagoya/items/7df2d4e05db724752a74

C++ Templates Part1 BASICS Chapter 3. Class Templates 3.2 Use of Class Template Stack stack1test.cpp
https://qiita.com/kaizen_nagoya/items/cd5fc49106fad5a4e9ed

ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed)
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1

C言語(C++)に対する誤解、曲解、無理解、爽快。
https://qiita.com/kaizen_nagoya/items/3f3992c9722c1cee2e3a

C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識
https://qiita.com/kaizen_nagoya/items/d89a48c1536a02ecdec9

'wchar.h' file not found で困った clang++ macOS
https://qiita.com/kaizen_nagoya/items/de15cd46d657517fac11

Open POSIX Test Suiteの使い方を調べはじめました
https://qiita.com/kaizen_nagoya/items/644d5e407f5faf96e6dc

MISRA-C 2012 Referenceに掲載している文献の入手可能性を確認
https://qiita.com/kaizen_nagoya/items/96dc8b125e462d5575bb

どうやって MISRA Example Suiteをコンパイルするか
https://qiita.com/kaizen_nagoya/items/fbdbff5ff696e2ca7f00

MISRA C まとめ #include
https://qiita.com/kaizen_nagoya/items/f1a79a7cbd281607c7c9

文書履歴

ver. 0.10 初稿 20180416
ver. 0.20 西山さんのご指摘による訂正。20180419
ver. 0.21 URL追記 20230215

最後までおよみいただきありがとうございました。

いいね 💚、フォローをお願いします。

Thank you very much for reading to the last sentence.

Please press the like icon 💚 and follow me for your happy life.

2
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0