今回は,米Microsoftの次期統合開発環境であるVisual C++ 2005 Express(ベータ2)を紹介します。プログラミング言語であるC++は,Bjarne Stroustrup氏が設計した国際標準プログラミング言語です。Microsoft社はこちらのページで,国際標準仕様への準拠をVisual C++ 2005 Expressの最大の特徴の1つと述べています。そこで今回は,簡単なサンプル・プログラムを使って,Visual C++ 2005 Expressの国際標準仕様への準拠度と開発環境としての特徴を見てみましょう。今回の記事を最後まで読むと分かりますが,Visual C++ 2005 Expressはセキュリティを確保するチェック機能も備えています。

Visual C++ 2005 Expressをインストールする

 Visual C++ 2005 Expressはこちらのページからダウンロードできます。指示に従ってダウンロードすると,基本的には次のようなソフトウエアがインストールされます。

  • 統合開発環境ソフトウエア(コンパイラ,リンカ,デバッガなど)
  • C++標準ヘッダー・ファイルとライブラリ

 ご覧のように,必要最小限のソフトウエアだけがダウンロードされるようになっています。Windowsアプリケーションを開発するために必要なプラットフォームSDK(PSDK)はダウンロードされません。今回は,PSDKをダウンロードせず,標準ヘッダー・ファイルとライブラリのみを使用します。なお,PSDKを使って,Windowsアプリケーションを開発実験してみたい人は,こちらの記事を参考にするとよいでしょう。

初めてのVisual C++ 2005 Expressサンプル・プログラム

 それでは最初のサンプル・プログラムを作ってみましょう。これから作成するサンプル・プログラムでは以下の基本的な技術項目を確認します。

  • C++はCのポインタをサポートしているのか
  • Visual C++ 2005 Expressは日本語を表示できるのか
  • Visual C++ 2005 ExpressはC++国際標準仕様に準拠しているのか

 Visual C++ 2005 Expressは現在ベータ2であることもあり,統合開発環境の詳しい操作説明は省略させていただきます。今回は,考え方だけを紹介することにします。筆者は,上記の3つの技術項目を確認するために,次のようなソースコードを用意してみました。

#include <iostream>

int main()
{

 const char* ch = "日経BP IT Pro連載担当:豊田孝\r\n";

 std::printf(ch);

 return (0);
}

 ソースコードの中ほどにある「std::printf(ch);」というコードの「std::」部分から判断できるように,筆者はC++の標準機能のみを使用しようとしています。第1行目では,Cのポインタが使われています。筆者は,このソースコードを作成する際には,次のような方針でVisual C++ 2005 Express開発環境の各値を設定しました。

  • 標準機能だけを使用するため,プロジェクト・ウィザード・コードは採用しない(空のプロジェクトを採用)
  • エラー検出は最も厳しく設定する(警告もエラーとする)
  • .NET関連コードは可能な限り生成させない
  • Microsoft言語拡張機能は一切無効にする
  • ビルド・ログには可能な限りの詳細情報を書き出す

図1●
図2●
図3●
図4●
図5●
図6●
図7●
 必要な設定をすべて行い,ビルドしてみると,図1[拡大表示]のようなエラーが返されました。このエラーは,次のようなことを述べています。

標準ヘッダー・ファイル「xstring」内にある「_Myfirstiter」という識別子が,宣言されずに使われている

 このエラー情報は,コンパイラにより構文エラーが検出されたことを示しています。しかも,その構文エラーは,標準ヘッダー・ファイル内で発生しています。筆者は当初当惑しましたが,次のようにしてこのエラーを取りのぞきました。

  • Microsoft言語拡張機能を有効にする

 Microsoft言語拡張機能を有効にしてビルドすると,今度は図2[拡大表示]のようなエラーが発生しました。このエラー情報は複雑ですが,次の点ははっきりしています。

  • コンパイル・エラーは発生していない
  • リンカ・エラーは発生していない
  • 「Embedding manifest...」というビルド処理を失敗している

 エラー情報をさらに注意してみると,「Embedding manifest...」処理は「mt.exe」というプログラムが担当しています。このプログラムはコンパイルとリンク処理の完了後に動作しているため,目的のプログラムはすでに完成しているはずです。筆者はこのような判断の下で,「Embedding manifest...」処理を無効にし,ビルドすることにしました。ビルド結果は図3[拡大表示]のようになりました。ご覧のように,警告もエラーもなくビルド処理が行われました。それではここで,これまでの経験を踏まえ,ビルド処理の基本的な方針を確認しておきましょう。

  • 標準機能だけを使用するため,プロジェクト・ウィザード・コードは採用しない(空のプロジェクトを採用)
  • エラー検出は最も厳しく設定する(警告もエラーとする)
  • .NETコード関連は可能な限り生成させない
  • Microsoft言語拡張機能は無効にしない
  • ビルド・ログには可能な限りの詳細情報を書き出す

 ここで念のために申し上げておきますが,筆者はVisual Studio .NET 2003環境でMicrosoft言語拡張機能を無効にしてビルドすることがありますが,今回のような問題は経験していません。このため,Visual C++ 2005製品版ではこのエラーは解決されると予想しています。完成したプログラムを実行すると,図4[拡大表示]のような画面が表示されます。ご覧のように,日本語もきちんと表示されています。それでは次に,第2のサンプル・プログラムの作成に移ります。

クラスを使った第2サンプル・プログラム

 私たちは,最初のサンプル・プログラム作成を通して,Visual C++ 2005 Express(ベータ2)のビルド時のコツを学びました。そこで今度は,習得したコツを活かしながら,次のような特徴を持つサンプル・プログラムを作成し,ビルドします。

  • Cのポインタは使用しない
  • 標準クラスを使用する

 筆者は,次のようなソースコードを用意しました。

#include <iostream>

int main()
{

 std::string str("日経BP IT Pro連載担当:豊田孝\r\n");

 std::cout.write(str.data(),std::streamsize(str.size()));

 return 0;
}

 ご覧のように,このソースコードでは,標準クラスである「string」クラスを使用しています。日本語文字列を画面に表示する際には,「cout」というオブジェクト(ostreamという標準クラスのオブジェクト)の「write」というメソッドを呼び出しています。このメソッドは,第1引数として文字列を,第2引数として表示する文字列の数を受け取ります。つまり,「write」メソッドは次のような機能を実装していることになります。

writeメソッドは,指定された文字列を,指定された分だけ画面に表示する

 このwriteメソッドはかなり分かりやすい機能を提供しています。writeメソッドを使用すれば,次のようなコードも簡単に記述できます。

std::cout.write(str.data(),std::streamsize(str.size()-6));

 このコードでは,文字列のすべてではなく,最後の6バイト分を表示しないように指示しています。それではビルドしてみましょう。今回のビルド処理では,図5[拡大表示]の機能も有効にすることにします。この機能は,Visual C++ 2005 Express(ベータ2)の新しい機能です。この機能は,次のような処理を実行してくれます。

この機能は,ソースコードから間接的に呼び出される関数やクラス内のメソッドが潜在的に抱えているセキュリティホールをチェックする

 この機能を有効にしてビルドすると,図6[拡大表示]のような結果が出されました。ご覧のように,警告が47個も検出され,正常にビルドできません。47個の警告には,例えば,次のような「バッファ・オーバーラン」警告や標準仕様違反警告などがあります。

(標準仕様違反警告)
c:\Program Files\Microsoft Visual Studio 8\VC\include\malloc.h(179) : warning C6387: '_Ptr' may be '0': this does not adhere to the specification for the function '_MarkAllocaS'.: defect path: 181,186

(バッファオーバーラン警告)
c:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(2051) : warning C6386: Buffer overrun while writing to 'argument 1': the writable size is '_Count*0' bytes,but '1' bytes may be written.: defect path: 2047,2048,2051

(潜在的なバッファオーバーラン警告)
c:\Program Files\Microsoft Visual Studio 8\VC\include\xlocale(1579) : warning C6412: Potential buffer overrun while writing to 'argument 4': the writable size is '1' bytes,but '_Last-_First*0' bytes may be written.: defect path: 1579

 このようなチェックが製品版でも行われるかどうかは不明ですが,筆者の感想を申し上げれば,警告の出ないソースコードを書くのは至難の業ではないでしょうか。筆者は,最終的に,ビルド条件を次のように緩めて,ビルドに成功しました(図7[拡大表示])。

  • 警告はエラーとして扱わないようにする

 確かにビルドには成功しています。しかし,デバッガの専門家の中には「警告はバグである」と主張する人もいます。ソフトウエアを開発することは,基本的には,既存のヘッダー・ファイルとライブラリ・ファイルを再利用することを意味します。今回の記事で確認したように,「コード分析」機能を有効にすると,標準ヘッダー・ファイルとライブラリが徹底調査され,47個もの警告が出されます。製品版では,このような警告が出ないサンプルコードを提供してもらいたいと思います。なお,今回使用したファイル類は,こちらからダウンロードできるようにしてあります。ビルド・オプションの設定方法などを参考してください。

今回のまとめ

  • Visual C++ .NET 2003の後継であるVisual C++ 2005 Expressのベータ2が公開された
  • Visual C++ 2005 Express(ベータ2)にはバッファ・オーバーランを厳しくチェックする機能がある
  • Visual C++ 2005 Express(ベータ2)には各種のビルド・オプションが用意されている
  • Visual C++ 2005 Express(ベータ2)の各種オプションは,適切に組み合わせて使用する必要がある