C++
coding
14882

N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(26)3.8 Object lifetime [basic.life] p72

はじめに

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.

(26)3.8 Object lifetime [basic.life]

p72

p72.cpp
#include <cstdlib>
struct B {
virtual void f();
void mutate();
virtual ~B();
};
struct D1 : B { void f(); };
struct D2 : B { void f(); };
void B::mutate() {
new (this) D2; // reuses storage — ends the lifetime of *this
f(); // undefined behavior
void* vp = this; // OK, this points to valid memory
}
void g() {
  void* p = std::malloc(sizeof(D1) + sizeof(D2));
  B* pb = new (p) D1;
  pb->mutate();
  &pb; // OK: pb points to valid memory    
  void* q = pb; // OK: pb points to valid memory
  pb->f(); // undefined behavior, lifetime of *pb has ended
}

struct C {
  int i;
  void f();
  const C& operator=( const C& );
};
const C& C::operator=( const C& other) {
  if ( this != &other ) {
    this->~C(); // lifetime of *this ends
    new (this) C(other); // new object of type C created
    f(); // well-defined
  }
  return *this;
}
C c1;
C c2;
void k(){
  c1 = c2; // well-defined
  c1.f(); // well-defined; c1 refers to a new object of type C
}

class T { };
struct B2 {
  ~B2();
};
void h() {
  B2 b;
  new (&b) T;
} // undefined behavior at block exit

struct B3 {
  B3();
  ~B3();
};
const B3 b;
void h() {
  b.~B3();
  new (const_cast<B3*>(&b)) const B3; // undefined behavior
}

int main(int argc, char *argv[], char *envp[]){
  k();
  std::cout << msg << std::endl;
  return EXIT_SUCCESS;
}
int main(int argc, char *argv[], char *envp[]){
  std::cout << msg << std::endl;
  return EXIT_SUCCESS;
}
$ ./cppgl17.sh p72
$ clang++ p72.cpp
p72.cpp:24:3: warning: expression result unused [-Wunused-value]
  &pb; // OK: pb points to valid memory    
  ^~~
1 warning generated.
Undefined symbols for architecture x86_64:
  "C::f()", referenced from:
      C::operator=(C const&) in p72-319c00.o
      k() in p72-319c00.o
  "B2::~B2()", referenced from:
      h() in p72-319c00.o
  "B3::B3()", referenced from:
      h2() in p72-319c00.o
      ___cxx_global_var_init in p72-319c00.o
  "B3::~B3()", referenced from:
      h2() in p72-319c00.o
      ___cxx_global_var_init in p72-319c00.o
  "vtable for B", referenced from:
      B::() in p72-319c00.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for D1", referenced from:
      D1::D1() in p72-319c00.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for D2", referenced from:
      D2::D2() in p72-319c00.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

$ g++-7 p72.cpp
Undefined symbols for architecture x86_64:
  "C::f()", referenced from:
      C::operator=(C const&) in ccLYcHyg.o
      k()    in ccLYcHyg.o
  "B2::~B2()", referenced from:
      h()    in ccLYcHyg.o
  "B3::B3()", referenced from:
      h2()    in ccLYcHyg.o
      __static_initialization_and_destruction_0(int, int) in ccLYcHyg.o
  "B3::~B3()", referenced from:
      h2()    in ccLYcHyg.o
      __static_initialization_and_destruction_0(int, int) in ccLYcHyg.o
  "vtable for B", referenced from:
      B::B()     in ccLYcHyg.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for D1", referenced from:
      D1::D1()    in ccLYcHyg.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for D2", referenced from:
      D2::D2()    in ccLYcHyg.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

検討事項

 リンクエラーにならない追記。
 内容の出力。

参考資料

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