[ C++で開発 ]

Visual C++ 10

Visual Studio 2010に含まれるC++開発環境がVisual C++ 10です。

コンパイラ特有のプリプロセッサ定義

定義シンボル 規定値
_MSC_VER
1600

コード生成のランタイム種類とプリプロセッサ定義(_MT, _DLL, _DEBUG)

Viusal C++のプロジェクト設定で、[構成プロパティ]>[C/C++]>[コード生成]のランタイム項目で選択可能なランタイム種類とその際自動で定義されるプリプロセッサ(デファイン)を試行確認してみました。

 ランタイム種類 _MT _DLL _DEBUG
 マルチスレッド(/MT)  ∨    
 マルチスレッドデバッグ(/MTd)  ∨    ∨
 マルチスレッドDLL(/MD)  ∨  ∨  
 マルチスレッドデバッグDLL(/MDd)  ∨  ∨  ∨
 参考)コマンドラインでランタイム指定なしにコンパイル  ∨    

なお、Visual C++ 10ではシングルスレッドの選択はありません。参考にあるようにコマンドラインでオプション指定なしにコンパイルを実行したときに_MTがデファインされています。

確認に使ったソースコードは次です。

#if defined(_DLL)
#  pragma message("_DLL is defined.")
#else
#  pragma message("_DLL isn't defined.")
#endif

#if defined(_MT)
#  pragma message("_MT is defined.")
#else
#  pragma message("_MT isn't defined.")
#endif

#if defined(_DEBUG)
#  pragma message("_DEBUG is defined.")
#else
#  pragma message("_DEBUG isn't defined.")
#endif

コンパイラの出力で結果を確認しました。

プロジェクト設定のコマンドライン表示

Viusal C++のプロジェクト設定で、[構成プロパティ]>[C/C++]>[コマンドライン]を見ると、_MT、_DLLは定義がありません。_DEBUGについては、デバッグビルドのときに/D "_DEBUG"が付与されていますが、これはなくてもよいかと思われます。

なお、ランタイム種類を一度も変更していない場合、上のようにランタイムオプションが表示されません。しかし、裏では実際にはランタイムオプションが指定されていました。プロパティ表示の問題かと思われます。

Visual C++のプロジェクト設定でランタイム種類を変更し、同じく[コマンドライン]を見ると、ランタイムオプションが表示されます。

一度変更すると表示されるようになります。

Windows SDK

Visual Studio 2010に含まれるWindows SDKは、ディレクトリ名を見ると「v7.0A」となっています。昔は「Platform SDK」と言ってましたが、Vistaの頃から「Windows SDK」という名に変わりました。

Windows SDKは、Windows API等のヘッダーファイル、ライブラリファイル、開発用ツール、サンプルコード、ヘルプなどが含まれています。Visual Studio でソフトウェアを開発する際は、ソフトウェアを実行するWindows OSと適合したバージョンのWindows SDKを使うのがよいと思います。

2012-10-14現在、「Windows SDK for Windows 7 and .NET Framework 4.0(バージョン 7.1)」が最新版です。

Hello World

Visual C++ 10(2010)でのHello Worldを作成します。

Win32コンソールアプリケーション版Hello World

Win32コンソールアプリケーションの推奨であるtchar.hを使用したマルチバイトコードセット/Unicodeセット両対応のコーディングを行います。

プロジェクトウィザードによるHelloWorldプロジェクト生成

[ファイル]メニュー>[新規作成]>[プロジェクト]を選択し、Visual C++のWin32コンソールアプリケーションを選択、プロジェクト名を例えば"HelloWorld"にします。その他はデフォルトのままプロジェクトを生成します。

生成されるソースファイルは次のようになりました。

HelloWorld
  ソースファイル
    HelloWorld.cpp
    stdafx.cpp
  ヘッダーファイル
    stdafx.h
    targetver.h
生成されたHelloWorld.cpp
// HelloWorld.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
        return 0;
}

ここで、main関数ではなく_tmain関数に、引数の文字型がcharではなく_TCHARになっています。これはマルチバイト文字セット/Unicode文字セット共通コードを生成するためです。

デフォルトのプロジェクト設定では文字セットに「Unicode文字セットを使用する」設定となっているので、_tmainや_TCHARはワイド文字系のものに置き換えられます。

生成されたstdafx.h
// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>



// TODO: プログラムに必要な追加ヘッダーをここで参照してください。

_TCHARなどの定義があるtchar.hと、なぜかstdio.hがインクルードされています。

デフォルトのプロジェクト設定ではプリコンパイル済みヘッダーを使用するとなっているので、stdafx.hに標準ライブラリやサードパーティ製ライブラリなどの変更をしないヘッダーファイルの#include文を記述すると、コンパイルが短縮されます。

生成されたtargetver.h
#pragma once

// SDKDDKVer.h をインクルードすると、利用できる最も上位の Windows プラットフォームが定義されます。

// 以前の Windows プラットフォーム用にアプリケーションをビルドする場合は、WinSDKVer.h をインクルードし、
// SDKDDKVer.h をインクルードする前に、サポート対象とするプラットフォームを示すように _WIN32_WINNT マクロを設定します。

#include <SDKDDKVer.h>

SDKDDKVer.hは、Windows SDKに含まれるファイルです。

print文の記述

HelloWorld.cppにprint文を追加します。

// HelloWorld.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <locale.h>

int _tmain(int argc, _TCHAR* argv[])
{
        _tsetlocale(LC_ALL, _T("japanese_jpn"));
        _tprintf(_T("こんにちは、世界!\n"));
        return 0;
}

ワイド文字(Unicode)を使用する場合、コンソールやファイルがUnicodeでないためUnicodeからコンソールやファイルに使用する文字コードに変換します。その変換先を指定しないと、ASCII文字以外が変換できません。そこで、C言語標準ヘッダーのlocale.hをインクルードし、setlocale関数をTCHARプリプロセッサ定義_tsetlocale経由で呼び出します。

また、printfもTCHARプリプロセッサ定義_tprintf経由で呼び出します。

文字列リテラルは、TCHARプリプロセッサ定義_Tで囲います。

実行

Visual C++ 上でビルドを実行すると、ソリューションディレクトリの下にリリースビルドかデバッグビルドかに応じてReleaseまはたDebugディレクトリが作られ、その中に実行ファイルが収められます。

Visual C++上でコンソールアプリケーションを実行すると、プログラムが終了するとコマンドプロンプトも一緒に閉じてしまいます。そこで、コマンドプロンプトを開き、そこで実行します。

C:\work\HelloWorld> Debug\HelloWorld.exe
こんにちは、世界!

C:\work\HelloWorld>

新機能

Visual C++ 10(2010)の新機能については、マイクロソフト(日本)が公開している次の記事に概要が列挙されています。

ISO/IEC 14882:2011(通称 C++11、別名 C++0x)で追加された機能の一部や、新しいCPUで導入された命令に対応した関数、新しいビルドツールMSBuild、同時実行ランタイムライブラリなどが新たに追加されています。

また、IntelliSenseが導入されています。

C++ 11標準(ISO/IEC 14882:2011)機能

Parallel Pattern Library(PPL)

C++ 11標準の機能を用いて並列処理を導入するライブラリ。OpenMPと類似しているが別物。OpenMPがプラグマ・ディレクティブを使っているのに対し、PPLはテンプレートを使用している。

記事よりコード断片を抜粋

parallel_for(0, height, [&] (int y) {
    for (int x = 0; x < width; ++x) { ... }
});

ほかにもいろいろな並列処理の制御が用意されています。

問題と解決または回避

SP1のインストールに失敗することがある

特定の条件(Visual Studioを一度アンインストールしてインストールしたときに、初回と2回目でインストールするコンポーネントに違いがあるとき)で、サービスパック1のインストールが失敗することがあります。

Visual Studioの使用メモリが増大し続ける(リーク)

Visual Studio 2010が環境によってメモリを著しく食いつぶしていく現象が発生します。

ソリューションファイルを開くのが遅い

画面描画がおかしい

搭載しているGPU(グラフィックスハードウェア)によっては、ハードウェア描画に問題があったり、ソフトウェア描画より性能劣化があるようです。

このページの7項に、ハードウェア描画を無効にすべきGPUのリストが掲載されています。

参考情報