melt日記

.NETすらまともに扱えないへたれのページ

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  111  : 記事  3  : コメント  491  : トラックバック  40

ニュース

わんくま同盟

わんくま同盟

C# と VB.NET の質問掲示板

iKnow!


Dictation



書庫

2008年5月29日 #

ボゴソート - Wikipedia


これ考えた奴天才だろ……。

posted @ 20:35 | Feedback (18)

2008年5月28日 #

() => {};

posted @ 15:06 | Feedback (3)

2008年5月27日 #

今のプロジェクト、毎週コードチェックの日があります。

他の人がチェックインしたファイルを読んで、ここは間違ってるとかここは変じゃない?ということをお互いに指摘し合います。


自分は下っ端なのでチェックすることはあまり無いのですが、それでも時々はチェックしています。


自分は現在のアプリケーションの仕様についてはあまり理解していないので、設計的な指摘よりもミクロな部分ばかり指摘しています。

今まで指摘してきたのは、例えばこんな感じです。


1.

std::auto_ptr<char> pBuffer(new char[BUFFER_SIZE]);

char は POD 型なので問題ないですが、std::auto_ptr は delete で解放するので delete[] で解放する必要のあるポインタに対して使ってはいけないと思います。


2.

(progress > total) ? total : progress

std::min を使った方が分かりやすいと思います。


3.

if (m_pHoge)
{
    delete m_pHoge;
    m_pHoge = NULL;
}

null ポインタに対する delete は、C++ 規格上は安全です。

よって、(よっぽどひどい operator delete を定義していない限りは)null チェックをする必要は無いと思います。


4.

std::string str = ...;
DWORD ret = GetFileAttributes(str.c_str());

str は std::string なので、GetFileAttributesA を使用する必要があると思います。


5.

CString str = ...;
TCHAR dest[MAX_LENGTH] = { 0 };
_tcsncpy(dest, str, _countof(dest));

str.GetLength() が _countof(dest) 以上だった場合、dest には null 文字がコピーされず(_tcsncpy の仕様)問題が発生すると思います。


6.


void ErrorMsg(const TCHAR* sz, const char* file, int line)
{
    TCHAR msg[1024];
    _stprintf_s(msg, _countof(msg), _T("%s[%d] : %s"), file, line, sz);
    ::MessageBox(NULL, msg, NULL, MB_OK);
}

1個目の %s は %hs を指定する必要があります。



コードチェックは、する側もされる側も良い勉強になりますし、未然にバグを防げることもあります(というかこれがメインなのですが)。

また、他人に見られるという意識を持つことによって、書く側もそれなりに気を使って書いてくれるようになります。


他人のコードを読んでけちを付ける指摘するのはなかなか面白いものがあります。

是非試して頂ければと思います。

posted @ 17:20 | Feedback (14)

2008年5月23日 #

僕らは技術力よりも第一印象で能力を判断されている/Tech総研


見た目で仕事能力を判断する奴全員氏んでいいよ。

posted @ 14:00 | Feedback (10)

2008年5月22日 #

ATL には、A2T だの CA2CT だのといった文字列変換マクロがあります。


ここを見れば分かるのですが、これらのマクロは時代によっていくつかの種類に分かれていたようで、最初に使われていたのは A2T だの A2W といったマクロのようです。

void foo(const char* p)
{
    USES_CONVERSION;
    TCHAR* pStr = A2T(p);
    ...
}

しかしこれは _alloca() を使っているため、下手をするとスタックオーバーフローを起こす危険性があったようです。


そこで作られたのが CA2T や CA2W といった、先頭に C の付いたマクロです。

これは固定サイズの配列をローカル変数として取っておき、そこに文字列を格納します。

もしローカルの配列に収まらなかった場合はヒープから領域を確保して、そこに文字列を格納します。

void foo(const char* p)
{
    CA2T pStr(p);
    ...
}

これなら _alloca() を使っていないので、普通にローカル変数を定義するのと同じ程度しかスタックを消費しません。


しかし、上記2つのコードを見れば分かるのですが、これらは機械的に置き換えられるものではなく、内容を精査した上で置き換える必要があります。

古くから使われている A2T 等のマクロが1万件とかある場合、さすがに手動で置き換える気はしません。


そこで使えるのが _EX とついたマクロ群。

これらを使えば、最初の例は以下のように置き換えることが出来ます。

void foo(const char* p)
{
    USES_CONVERSION_EX;
    TCHAR* pStr = A2T_EX_DEF(p);
}

USES_CONVERSION は USES_CONVERSION_EX に、A2T は A2T_EX_DEF に変更するだけです。

A2T_EX_DEF というのはどういう動作になるかというと、内部的には _ATL_SAFE_ALLOCA を使っているので、ある程度のサイズ(デフォルトは 1024 バイト)までは _alloca() によって確保しようとして、それ以上になるとヒープから確保します。

また、1024 バイト以下であっても _alloca() によってスタックオーバーフローが起きてしまう場合、ヒープから確保してくれます。


A2T や A2W だとスタックオーバーフローが起きてしまうから使ってはダメ!と言われたけれども件数が多くて手動で直すのが非常に面倒な場合は、このマクロが使えそうな気がします。

posted @ 10:53 | Feedback (3)

2008年4月24日 #

冷蔵庫にキリンを入れる方法を読んで、何で状態が入れ子になるんだろう?と思ったので、状態遷移図を書いてみました。

f:id:melt_slinc:20080424153439p:image

ほら、入れ子になんかならないじゃん?とか思ったのですが、何か違う。絶対違う。

多分「扉が開いている状態」と「扉が閉まっている状態」という2つの状態で考えるのが普通だろうから、多分こんな風になるのかな?

f:id:melt_slinc:20080424154029p:image

確かに入れ子になってる。

posted @ 15:43 | Feedback (9)

2008年4月22日 #

std::stack<> を使うたびにいつも思うのですが、何で pop() の戻り値は void になっているのでしょうか?

このせいでわざわざ top() で先頭の値を持ってきて一時変数に確保した後 pop() を実行する必要があります。

std::stack<int> st;
st.push(10);

// int n = st.pop(); // こうやって書くことが出来ない
int n = st.top();
st.pop();

これについてずっと不満を覚えていたのですが、最近 Exceptional C++ を読んで、なぜ void になっているのか、というのを知りました。


pop() が void になっている理由は、例外安全を保証するためだそうです。


例えば T を返す pop() メソッドの実装は、次のように書くことが出来ます。

T pop()
{
    assert(size_ > 0);

    size_t index = size_ - 1; // 1

    T value = ptr_[index];    // 2
    Destruct(&ptr_[index]);   // 3
    size_--;                  // 4
    return value;             // 5

}

T のコピーコンストラクタが例外を投げる可能性がある場合、2 と 5 で例外が発生する可能性があります。

例外が発生しても呼び出し前の状態を保持する程度の安全性を保証する場合、例えば 2 で例外が発生しても size_ は変更されていないので安全です。

しかし、5 で例外が発生した場合、size_ は既に変更されているので、これは例外安全とは言えません。


例外仕様は設計に影響します。

例外安全を考えると、std::stack<> が pop() で T を返すことは不可能なのです。

なので、pop() は void とし、T& を返す top() というメソッドでスタックの先頭への参照を返してもらう必要があるのです。



例外って難しいです...。

posted @ 11:46 | Feedback (3)

2008年4月15日 #

PostMessage をするとき、引数を LPARAM と WPARAM にキャストするのですが、数が多い場合はキャストするのがどうも面倒です。

ということでこんなのを作ってみました。


template<class WParam, class LParam>
inline BOOL PostMessageT(HWND hWnd, UINT uMsg, WParam wParam, LParam lParam)
{
    return ::PostMessage(hWnd, uMsg, (WPARAM)wParam, (LPARAM)lParam);
}
template<class WParam, class LParam>
inline BOOL SendMessageT(HWND hWnd, UINT uMsg, WParam wParam, LParam lParam)
{
    return ::SendMessage(hWnd, uMsg, (WPARAM)wParam, (LPARAM)lParam);
}

WPARAM や LPARAM への C スタイルでの変換が可能なら、キャストせずに PostMessage, SendMessage できます。

SendMessageT(hCtrl, CB_ADDSTRING, 0, TEXT("hoge"));

Hoge hoge;
enum EValue { value = 100 };
PostMessageT(hWnd, WM_USER + 100, value, &hoge);

自分の周りの人には好評でした……正直微妙な気分でしたが。

下回りならまだしも、上の方でバリバリに WindowsAPI を直接叩くのは勘弁して下さい……。

posted @ 10:50 | Feedback (6)

2008年4月11日 #

Visual Studio 2008 Standard Edition がもらえると聞いて、思わず申し込んでしまいました。

4/15 は人数いっぱいだったので 4/16 に登録しました。


とりあえずレベルは 200 ということなので、あまり気構えずに、

  • 10:00-10:50 VD-24 ここから始める! Windows Vista の活用術
  • 11:10-12:00 VD-25 新しい Office で仕事を改善 2007 Office sysetem で実現する理想のワークスタイル
  • 13:20-14:10 NA-36 強化されたセキュアでハイパフォーマンスな PHP の実行環境とその実装方法
  • 14:30-15:20 NA-37 "次世代 Web" を攻略せよ! Silverlight & ASP.NET Futures
  • 16:00-16:50 NA-38 Visual Studio 2008 を活用したチーム開発のベストプラクティス
  • 17:10-18:00 NA-39 Visual Studio 2008 による実践的パフォーマンス チューニング & テスト

この辺に参加してみようかなと思います。


さて、今から休み申請してきます。通るかなぁ……。

posted @ 16:00 | Feedback (4)

2008年3月31日 #

Boost 1.35.0 がリリースされたらしいという話を聞いて、どんだけパワーアップしたんだろと覗いていたところ、Boost.Thread に対する変更があったみたいです。


で、その詳細を読んでみると……。

Threads can be interrupted at interruption points.

interrupted 機構キタ━━━━(゚∀゚)━━━━!!

こいつが無いと join や wait や sleep で待っているスレッドを安全に終了させるのがかなり面倒だったので、かなり嬉しいです。


他にも面白そうな変更があれこれ。at_thread_exit() とか、1.34.1 の TSS の内部実装を見て、この機構欲しいと思ってたらほんとに実装されてました。Boost.Thread 始まりすぎです。

今のプロジェクトでは 1.34.1 を使ってますが、次のプロジェクトでは 1.35.0 を使えるように打診してみるしか。

posted @ 10:40 | Feedback (5)