C++
coding
14882

N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(46)5.3.4 New [expr.new] p121

はじめに

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.

(46)5.3.4 New [expr.new]

p121

p121.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf 
#define msg "p121.cpp (46)5.3.4 New [expr.new]"

#include <iostream>
#include <memory>


T x(e);

new auto(1); // allocated type is int
auto x = new auto(a); // allocated type is char, x is of type char*

new int * i; // syntax error: parsed as (new int*) i, not as (new int)*i

new int(*[10])(); // error

(new int) (*[10])(); // error

new (int (*[10])());

void mergeable(int x) {
// These allocations are safe for merging:
std::unique_ptr<char[]> a{new (std::nothrow) char[8]};
std::unique_ptr<char[]> b{new (std::nothrow) char[8]};
std::unique_ptr<char[]> c{new (std::nothrow) char[x]};
g(a.get(), b.get(), c.get());
}
void unmergeable(int x) {
std::unique_ptr<char[]> a{new char[8]};
try {
// Merging this allocation would change its catch handler.
std::unique_ptr<char[]> b{new char[x]};
} catch (const std::bad_alloc& e) {
std::cerr << "Allocation failed: " << e.what() << std::endl;
throw;
}
}

operator new(sizeof(T))
operator new(sizeof(T), std::align_val_t(alignof(T)))

operator new(sizeof(T), 2, f)
operator new(sizeof(T), std::align_val_t(alignof(T)), 2, f)

operator new[](sizeof(T) * 5 + x)
operator new[](sizeof(T) * 5 + x, std::align_val_t(alignof(T)))

operator new[](sizeof(T) * 5 + x, 2, f)
operator new[](sizeof(T) * 5 + x, std::align_val_t(alignof(T)), 2, f)

struct S {
// Placement allocation function:
static void* operator new(std::size_t, std::size_t);
// Usual (non-placement) deallocation function:
static void operator delete(void*, std::size_t);
};
S* p = new (0) S; // ill-formed: non-placement deallocation function matches
// placement allocation function

int main(int argc, char *argv[], char *envp[]){
//  std::cout << "p1="<<p1 <<" q1=" << q1 << " pi1="<<pi1<<" pci1="<<pci1<<std::endl;
  std::cout << msg << std::endl;
  return EXIT_SUCCESS;
}
$ ./cppgl17.sh p121
$ clang++ p121.cpp
p121.cpp:8:1: error: unknown type name 'T'
T x(e);
^
p121.cpp:8:5: error: unknown type name 'e'
T x(e);
    ^
p121.cpp:10:1: error: expected unqualified-id
new auto(1); // allocated type is int
^
p121.cpp:11:6: error: redefinition of 'x' as different kind of symbol
auto x = new auto('a'); // allocated type is char, x is of type char*
     ^
p121.cpp:8:3: note: previous definition is here
T x(e);
  ^
p121.cpp:13:1: error: expected unqualified-id
new int * i; // syntax error: parsed as (new int*) i, not as (new int)*i
^
p121.cpp:15:1: error: expected unqualified-id
new int(*[10])(); // error
^
p121.cpp:17:2: error: expected unqualified-id
(new int) (*[10])(); // error
 ^
p121.cpp:17:2: error: expected ')'
p121.cpp:17:1: note: to match this '('
(new int) (*[10])(); // error
^
p121.cpp:19:1: error: expected unqualified-id
new (int (*[10])());
^
p121.cpp:26:1: error: use of undeclared identifier 'g'
g(a.get(), b.get(), c.get());
^
p121.cpp:39:14: error: expected parameter declarator
operator new(sizeof(T))
             ^
p121.cpp:39:14: error: expected ')'
p121.cpp:39:13: note: to match this '('
operator new(sizeof(T))
            ^
p121.cpp:40:1: error: expected function body after function declarator
operator new(sizeof(T), std::align_val_t(alignof(T)))
^
p121.cpp:57:1: error: unknown type name 'S'
S* p = new (0) S; // ill-formed: non-placement deallocation function matches
^
p121.cpp:57:16: error: unknown type name 'S'
S* p = new (0) S; // ill-formed: non-placement deallocation function matches
               ^
15 errors generated.

$ g++-7 p121.cpp
p121.cpp:8:1: error: 'T' does not name a type
 T x(e);
 ^
p121.cpp:10:1: error: expected unqualified-id before 'new'
 new auto(1); // allocated type is int
 ^~~
p121.cpp:13:1: error: expected unqualified-id before 'new'
 new int * i; // syntax error: parsed as (new int*) i, not as (new int)*i
 ^~~
p121.cpp:15:1: error: expected unqualified-id before 'new'
 new int(*[10])(); // error
 ^~~
p121.cpp:17:2: error: expected unqualified-id before 'new'
 (new int) (*[10])(); // error
  ^~~
p121.cpp:17:2: error: expected ')' before 'new'
p121.cpp:19:1: error: expected unqualified-id before 'new'
 new (int (*[10])());
 ^~~
p121.cpp: In function 'void mergeable(int)':
p121.cpp:26:1: error: 'g' was not declared in this scope
 g(a.get(), b.get(), c.get());
 ^
p121.cpp: At global scope:
p121.cpp:39:13: error: expected constructor, destructor, or type conversion before '(' token
 operator new(sizeof(T))
             ^
p121.cpp:57:1: error: 'S' does not name a type
 S* p = new (0) S; // ill-formed: non-placement deallocation function matches
 ^

検討事項

 コンパイルエラーにならない修正。
 内容の出力。

参考資料

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