2011-01-30

エレヴェン

まずはこの動画を見てほしい。


いや、最先端だね。音声認識エレベーターとは。
でもスコティッシュアクセントには対応していなかったようだ。

これを同僚に見せられたときは思わず大爆笑してしまった。
うちの会社のCEOとマネージャーの一人はスコットランド人だけどね!!

2011-01-15

LinuxをUSBからインストール

をするための準備の話。
ちょっと古めのデスクトップが転がってて、OSが入ってない。Windowsはもちろんない。ということで、Linuxを入れようと思ったのだが、現在使ってるノートPCにはCDROMがない。

っでちょっと調べてみたらUSBからインストールできるらしい。ということでブータブルUSBを作成する。
手順。
  1. syslinuxを落としてくる。
  2. DAEMON Tool Liteを落としてインストール。
  3. Linuxのisoイメージを落とす。
  4. 3.を2.のツールでマウントして、中身をUSBドライブにコピー。
  5. USBドライブにisolinuxってフォルダがあるので、それをsyslinuxに変更。
  6. 5.のフォルダの中にisolinux.cfgというファイルがあるので、syslinux.cfgに変更
  7. syslinux.exeを叩く。(syslinux.zipで落としたなら、中のwin32フォルダにある)
    C:\> syslinux.exe -maf F:
    (F: はUSBドライブ名。これをC:とか自分のHDDにすると多分えらいことになる)
    本当は-maでいいんだと思うけど、僕のUSBはリムーバブルと認識されてなくて、強制書き換えの-fが必要だった。
たった(結構あるな)これだけ。

他にも、UNetbootinってツールも試したけど、こいつにはひどい目に合わされた。バージョンが悪いのか(最新版だけど)、そもそもCDイメージをUSBにコピーするだけのツールなのか知らないけど、ブータブルなUSBならない。

これで上手くいったらSSDを買って自分のノートにLinuxを入れよう。
(その前に死んだバッテリーを換えないと。ACアダプタ抜いたら即死ぬノートPCってノートの魅力0なんですけど)

2011-01-12

ワイド文字列

いろいろやってて壁にぶち当たった・・・
C言語で文字列を扱うことがこんなに面倒だとは、知ってたけど改めて痛感。
char = 1 byteはいいとして、
wchat_t != 4 byte ってか処理系依存って結構厳しい。
UCS4を内部エンコードに使いたかった(すでに過去形)のだが、WindowsのVCとCygwin GCCだとwchat_tは2byte。(Linuxだと4byteらしいけど、試してない)
マクロで
typedef wchar_t ucs4char;
#define UC(str) L##str
なんてことしたかったんだけど、無理になった・・・orz
そもそも
typedef int32_t ucs4char; /* 符号付 4byte(EOFは大抵-1だし) */
static const ucs4char msg[4] = {0x3042, 0x3044, 0x3046 0x0}; /* あいう */
static const char* cmsg = "abcde";
ってのがアセンブラ上だとなんかあんまり美味しくないようになってる。こんな感じで。
L0  .long 0x3042
    .long 0x3044
      :
_msg .long L0
     .def __somewhere
L1  .ascii "abcde\0"
    .text
_cmsg .long L1
なんか、静的に配列確保してて(そういう宣言だから当たり前だが)、あんまり静的な文字列な感じがしない。

あと、C内部で文字列を扱う際に、C文字列からUCS4変換する必要が出てくるので、文字列のコピーがどうしても必要になり、アロケーションが走る。使い捨ての文字列とかにアロケーションは走ってほしくない。

Ypsilon方式にするか。ファイルのエンコーディング -> UCS4(中間表現) -> UTF8(内部文字列)とするとCで使ってる文字列はそのまま流用できそう。
改修がすごく広範囲にわたるが今のうちにやったほうがいいだろうなぁ。

2011-01-08

Boehm GCを読む

正直涙が出そうになっているが、現在の所分かった(つもりでいる)部分のメモ。

    基本的な部分
  1. ヒープとして渡されるポインタはヘッダー情報を保持していない(ある意味当たり前)
  2. ファイナライザはオブジェクト(ここではポインタ)に持たせず別に管理している(finalizable_objectを格納するハッシュテーブル)
  3. ヒープ内部はOSのページブロック(基本4KB)ごとに分けられている(ちと不安)

    曖昧な理解の部分
  1. GCのヒープはGC_arraysという構造体で一括管理してるっぽい。
  2. top_indexとかbottom_indexとか2KBくらいの配列を確保してるけど、この中に実際のヒープのヘッダーが入ってるっぽい。

あ、でも
struct hblkhdr
{
  struct hblk *hb_next;
  struct hblk *hb_prev;
  struct hblk *hb_block;
  /* 以下略 */
};
struct hblk
{
  char hb_body[HBLKSIZE];
};
/* HBLKSIZEは基本4KB */
なんてなってるから、ヘッダーにメタ情報を持たせて(使える領域とか、どんなオブジェクト用かとか、残りブロックサイズとか)、ページブロック以下のサイズのオブジェクトに対してはhb_blockからみ使用部分を割り当てるなんて方法なのかも。
可変構造体にしないのは、最大限にヒープを使うためなのか、可搬性のためなのかどっちなんだろう?

2011-01-04

これってOK?

C言語でこんなのって合法?
static int s_value[5] = {1, 2, 3, 4, 5};
struct rec_t {
  int v[1];
};
static struct s_rec_t
{
  rec_t v[1];
} myth = {
  { s_value }
};
用は構造体の初期化だと思うんだけど、rec_tがint*なら合法なのはいいとして、この場合だとどうなるんだろう?
そのまま見ると1個しかない配列に対して5個入れてるから違法臭いけど、ポインタ自体を書き換えるのであれば合法っぽくもある。
実際、
struct string_t
{
   int size;
   char value[1];
};
---
string_t *s = (string_t*)malloc(sizeof(string_t) + sizeof(char)*10);
strcpy(s->value, "abcdefghi");
s->value[10] = '\0';
なんてのは合法なんだよね。
(いや、仕様書を確認したわけじゃないけど、よく見るテクニックだからそう思ってる。実際char[1]をchar*にするとセグるし、当たり前だが)
ただ、この場合だとポインタを書き換えるのではなく、連続したメモリという扱いになるのかな?
最初のケースだと純粋に書き換えてるから、うっかり鼻から悪魔が出てきても文句が言えなさそうな気はするが。
う~ん。

2011-01-01

謹賀新年

あけましておめでとうございます。

旧年はお世話になりました。本年もよろしくお願いいたします。

去年(一昨年からか?)やってる個人プロジェクト、まだあんまり形になってないけど、今年中にはなんらかの形にしたいなぁ。
個人的にもう少しな感じがしてる。(気が変わって作り直しをしなければ。何度やったか・・・)

今年はいい年になりそうな気がする。