Seaside Laboratory

Posts

Visual Studio 2008 Express Edition をインストール

VC++ 6.0 を使っていた頃、気まぐれで触った BCC が思いのほか良く、開発環境を全て BCC に移してしまったので長いこと VC++ と無縁の開発生活を送っていたが、さすがに BCC も古くなってきたので VC++ 2008 へ移ることにした。

「VC++ 2008 も十分古いダルォォ?」という話もあるが、ユーザー登録をせずに気軽に使えるバージョンとなると候補は 2008 しかない。この環境移行を機に C++11 で追加された auto、Range-based for、std::initializer_list あたりを使ってみたかったが、規格が決まる前に作られたコンパイラなので当たり前ながらサポートされていない、残念。

Visual C++ 2008 Express のインストール

通常なら Microsoft のサイトから ISO イメージをダウンロードして、それを DVD に焼いてインストール…となるが、Windows 8 なら ISO イメージのマウントがサポートされているので、クリックするだけでインストールできてしまう。インストール時に表示されるダイアログの内容をよく読んでおかないと、ゴミ (Silverlight 等) が便乗インストールされてしまうので注意。

調子良く進めばインストール自体はそんなに時間がかからず終了する。「調子良く」と書いたのは、もう一台の PC にインストールした際、.NET Framework 関連のインストール過程で何故かクラッシュしてしまったという理由がある。

SQL Server 関連とリモートデバッガは使う予定がないので、以下のソフトはアンインストールした。

  • Microsoft SQL Server 2008 Management Objects
  • SQL Server System CLR Types
  • Microsoft Visual Studio 2008 リモート デバッガ ライト (x64)

DirectX SDK のインストール

DirectX SDK にはサポートしている VC++ のバージョンというものがあるらしく、あまり離れたバージョンを使うとビルドエラーが出て使えないらしい。

試しに適当なバージョンの SDK を入れてみたら、DirectMusic 関連のヘッダーファイルが収録されていない (サポート終了) のが原因でビルドエラーになってしまった。DirectMusic をサポートしている SDK の最終バージョンは August 2007 ということなので、入れ直してから再度チャレンジしてみたら無事コンパイルすることができた。

SDK 付属のインストーラーだと使いもしないユーティリティーがインストールされたり、「Convert to file format」というエクスプローラー拡張メニューが追加されたりしてうざいので、7-Zip で強制解凍して、インクルードファイルとライブラリだけを使うという方法がおすすめ。

Function call with parameters that may be unsafe

STL の algorithm は vector のようなコンテナだけでなく組み込み配列も扱えるので、バッファの初期化やコピーをするときには std::fill や std::copy を使ったりしているのだが、プログラム設計上安全な操作だとわかっていてもバッファオーバーフローの可能性があるとして警告が表示されてしまう。

この警告を抑制するための定数 _SCL_SECURE_NO_WARNINGS が用意されているので、コンパイラの定数指定に追加して警告が出ないようにした。

This function or variable may be unsafe.

C 標準ライブラリを使っていると、よりセキュアな "_s" が付いたバージョン、例えば fopen なら fopen_s を使うように薦めてくる。セキュアなのに越したことはないが、MS 独自の非標準関数を使うのは嫌なので、先程と同様のやり方で _CRT_SECURE_NO_WARNINGS という定数を定義して警告が出ないようにした。

bool 値へのキャスト

特定のビットが立っているか判定して、結果を bool 値に格納するとき、

// 読み込み可能属性ビットが立っているか
bool bReadable = (uAttribute & uReadableMask);

このようなコードを書くと「'unsigned int' から 'bool' へ切り詰めます。」というエラーが出る。キャストしているので当たり前のエラーではあるが、ビット操作をするときはついつい書いてしまうコードなので、

bool bReadable = (uAttribute & uReadableMask) != 0;

という形で自然なキャストを行うようにした。

fstream とマルチバイトのファイル名

今まで正常に読み込めていたファイルが読み込めなくなったので、デバッガーで追跡してみると ifstream にマルチバイトのファイル名を与えたときだけ open に失敗していた。

STL のロケールについて

STL のロケールはあまり注目されることはありませんでしたが、ある時、(一部の) Windows 系プログラマの注目を浴びることになりました。

それは…
Visual C++ 2005 では、fstream 系に日本語のパスを与えると実行時エラーになる!
という問題が起きたからです。

マルチバイトのファイル名をワイド文字に変換する際に、ロケールが設定されていないと正しく変換できず、失敗するらしい。

Visual C++ 2010 を使えば問題なく動作するとのことだが、今使っているのは 2008 なのでロケールを設定する方向で対処することにした。ロケールは各ストリーム毎に局所的に設定するのが望ましいと書かれていたが、新しいバージョン (2010 以降) で解決するということと、fstream を使用している箇所が多かったので、大域で設定することにした。

#include <locale>

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
    std::locale::global( std::locale( "japanese" ) );