謎's キッチン

謎のひとりごと。Amazon欲しい物リストはこちら: https://www.amazon.co.jp/hz/wishlist/ls/CCPOV7C6JTD2

右辺値参照とムーブセマンティクス

C++11は良く分からんので、C言語で。参照でもないけど、実装は似たようなもん。デコンストラクタ問題やオーバーロード演算子オーバーライドが無いので別物だけど、これはこれで使い道ある気がする。

moveについては、safe_freeのような趣きがあって良ろしいかな。unique_ptrのようなものを作るのにはcoccinelleのようなソフトの支援を借りなければならないけど、coccinelleならコンテキストに依存した複雑な制約を課すことが容易なので、それはそれで色々出来そう。

#include <stddef.h>
#include <stdio.h>
#include <alloca.h> 

/*
static inline void *_move(void **p){
  void *q = *p;
  *p = NULL;
  return q;
}
#define move(p) _move((void **)&p)

#define to_rvref(v) ((*(volatile typeof(v)*)alloca(sizeof(v))) = v,alloca(0)) // buggy
*/

// GCC拡張
#define move(p) ({typeof(p) __q = p; p = NULL; __q;})
#define to_rvref(v) ({typeof(v)* __p = alloca(sizeof(v)); *__p = v; __p;})

int *test(){
  int *u = NULL, *v = to_rvref(12345678);
  printf("%d\n", *v);
  u = move(v);
  printf("%d\n", *u);
  printf("%p\n", v);
  return u;
}

__attribute__((optimize("O0")))
void breakstack(){
   int **p = alloca(sizeof(int*)*3);
   *p++ = NULL;
   *p++ = NULL;
   *p++ = NULL;
}

int main(){
  int *p = test();
  breakstack();
  printf("%d\n", *p); // broken
}